File size: 9,261 Bytes
bb869fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
509fa5d
 
bb869fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72542d2
bb869fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
import streamlit as st
import json
from rule_extractor import get_rules_from_url, format_rules_for_display
from doc_analyzer import analyze_document

def combine_rules(url_rules, pasted_rules):
    """Combine URL-extracted rules and manually pasted rules"""
    combined_rules = ""
    
    # Check if URL rules are in JSON format and convert if needed
    if url_rules and (url_rules.strip().startswith('[') or url_rules.strip().startswith('{')):
        try:
            # Try to parse as JSON
            rules_data = json.loads(url_rules)
            if isinstance(rules_data, list) and len(rules_data) > 0:
                rules_data = rules_data[0]
            
            # Format the rules
            url_rules = format_rules_for_display(rules_data)
        except Exception as e:
            # If parsing fails, use as is
            pass
    
    # Add URL-extracted rules if available
    if url_rules:
        combined_rules += url_rules
    
    # Add pasted rules if available
    if pasted_rules:
        if url_rules:  # If we already have URL rules, add a separator
            combined_rules += "\n\n## Additional Manually Pasted Rules\n\n" + pasted_rules
        else:  # If no URL rules, just use pasted rules
            combined_rules = "# Manually Pasted Rules\n\n" + pasted_rules
    
    return combined_rules

st.set_page_config(
    page_title="FormatReview",
    page_icon="πŸ”Ž",
    layout="wide",
)

st.title("FormatReview")
st.markdown("Analyze your manuscript against any journal's formatting guidelines.")

# Initialize session state for storing rules
if "rules" not in st.session_state:
    st.session_state.rules = None
if "results" not in st.session_state:
    st.session_state.results = None
if "url_rules" not in st.session_state:
    st.session_state.url_rules = None
if "pasted_rules" not in st.session_state:
    st.session_state.pasted_rules = None

# Create tabs
tab1, tab2, tab3 = st.tabs(["Document Upload", "Formatting Rules", "Analysis Results"])

with tab1:
    # --- UI Components ---
    uploaded_file = st.file_uploader("Upload your manuscript (PDF or DOCX)", type=["pdf", "docx"])
    
    # Rules input section
    st.subheader("Formatting Rules")
    st.markdown("You can provide formatting rules by URL, paste them directly, or both.")
    
    # URL input
    journal_url = st.text_input("Enter the URL to the journal's 'Instructions for Authors' page (optional if pasting rules)")
    
    # Pasted rules input
    pasted_rules = st.text_area(
        "Or paste formatting rules directly (optional if providing URL)",
        height=200,
        placeholder="Paste journal formatting guidelines here..."
    )
    
    if st.button("Analyze Document"):
        if uploaded_file is None:
            st.error("Please upload your manuscript.")
        elif not journal_url and not pasted_rules:
            st.error("Please either enter the journal's URL or paste formatting rules.")
        else:
            # Initialize combined rules
            combined_rules = ""
            
            # Extract rules from URL if provided
            if journal_url:
                with st.spinner("Extracting rules from URL..."):
                    url_rules = get_rules_from_url(journal_url)
                    st.session_state.url_rules = url_rules
                    if url_rules:
                        combined_rules += url_rules
            
            # Add pasted rules if provided
            if pasted_rules:
                st.session_state.pasted_rules = pasted_rules
                if journal_url:  # If we already have URL rules, combine them
                    # Make sure URL rules are formatted before combining
                    if st.session_state.url_rules and (
                        st.session_state.url_rules.strip().startswith('[') or 
                        st.session_state.url_rules.strip().startswith('{')
                    ):
                        try:
                            # Try to parse as JSON
                            rules_data = json.loads(st.session_state.url_rules)
                            if isinstance(rules_data, list) and len(rules_data) > 0:
                                rules_data = rules_data[0]
                            
                            # Format and update the URL rules
                            formatted_url_rules = format_rules_for_display(rules_data)
                            st.session_state.url_rules = formatted_url_rules
                        except Exception as e:
                            # If parsing fails, use as is
                            pass
                    
                    combined_rules = combine_rules(st.session_state.url_rules, pasted_rules)
                else:  # If no URL rules, just use pasted rules
                    combined_rules = "# Manually Pasted Rules\n\n" + pasted_rules
            
            # Store the combined rules
            st.session_state.rules = combined_rules
            
            # Analyze the document
            with st.spinner("Analyzing document..."):
                st.session_state.results = analyze_document(uploaded_file, st.session_state.rules)
            
            st.success("Analysis complete! View the results in the 'Analysis Results' tab.")

with tab2:
    st.header("Formatting Rules")
    
    if st.session_state.url_rules or st.session_state.pasted_rules:
        # Display URL-extracted rules if available
        if st.session_state.url_rules:
            st.subheader("Rules Extracted from URL")
            st.markdown(st.session_state.url_rules)
        
        # Display pasted rules if available
        if st.session_state.pasted_rules:
            st.subheader("Manually Pasted Rules")
            st.text_area("", value=st.session_state.pasted_rules, height=150, disabled=True)
        
        # Display combined rules used for analysis
        if st.session_state.rules and (st.session_state.url_rules and st.session_state.pasted_rules):
            st.subheader("Combined Rules (Used for Analysis)")
            
            # The combined rules should already be formatted, but check just in case
            if isinstance(st.session_state.rules, str) and (
                st.session_state.rules.strip().startswith('[') or 
                st.session_state.rules.strip().startswith('{')
            ):
                try:
                    # Try to parse as JSON
                    rules_data = json.loads(st.session_state.rules)
                    if isinstance(rules_data, list) and len(rules_data) > 0:
                        rules_data = rules_data[0]
                    
                    # Format and display the rules
                    formatted_rules = format_rules_for_display(rules_data)
                    st.markdown(formatted_rules)
                except Exception as e:
                    # If parsing fails, just display as is
                    st.markdown(st.session_state.rules)
            else:
                # If not JSON, just display as is
                st.markdown(st.session_state.rules)
    else:
        st.info("Provide formatting rules via URL or direct input to view them here.")

with tab3:
    st.header("Analysis Results")
    if st.session_state.results:
        results = st.session_state.results
        
        if "error" in results:
            st.error(results["error"])
        else:
            # Display summary
            st.subheader("Summary")
            summary = results.get("summary", {})
            st.write(f"**Overall Assessment**: {summary.get('overall_assessment', 'N/A')}")
            st.write(f"**Total Issues**: {summary.get('total_issues', 'N/A')}")
            st.write(f"**Critical Issues**: {summary.get('critical_issues', 'N/A')}")
            st.write(f"**Warning Issues**: {summary.get('warning_issues', 'N/A')}")
            
            # Display recommendations
            st.subheader("Recommendations")
            recommendations = results.get("recommendations", [])
            if recommendations:
                for rec in recommendations:
                    st.write(f"- {rec}")
            else:
                st.write("No recommendations.")
                
            # Display detailed report
            st.subheader("Detailed Report")
            issues = results.get("issues", [])
            if issues:
                for issue in issues:
                    severity = issue.get('severity', 'N/A').lower()
                    message = f"**{issue.get('severity', 'N/A').upper()}**: {issue.get('message', 'N/A')}"

                    if severity == 'critical':
                        st.error(message)
                    elif severity == 'warning':
                        st.warning(message)
                    elif severity == 'info':
                        st.info(message)
                    else:
                        st.success(message)

                    st.write(f"**Location**: {issue.get('location', 'N/A')}")
                    st.write(f"**Suggestion**: {issue.get('suggestion', 'N/A')}")
                    st.divider()
            else:
                st.success("No issues found.")
    else:
        st.info("Analyze a document to view results here.")