scientific-writer 2.2.1__py3-none-any.whl → 2.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of scientific-writer might be problematic. Click here for more details.
- scientific_writer/.claude/WRITER.md +748 -0
- scientific_writer/.claude/settings.local.json +30 -0
- scientific_writer/.claude/skills/citation-management/SKILL.md +1046 -0
- scientific_writer/.claude/skills/citation-management/assets/bibtex_template.bib +264 -0
- scientific_writer/.claude/skills/citation-management/assets/citation_checklist.md +386 -0
- scientific_writer/.claude/skills/citation-management/references/bibtex_formatting.md +908 -0
- scientific_writer/.claude/skills/citation-management/references/citation_validation.md +794 -0
- scientific_writer/.claude/skills/citation-management/references/google_scholar_search.md +725 -0
- scientific_writer/.claude/skills/citation-management/references/metadata_extraction.md +870 -0
- scientific_writer/.claude/skills/citation-management/references/pubmed_search.md +839 -0
- scientific_writer/.claude/skills/citation-management/scripts/doi_to_bibtex.py +204 -0
- scientific_writer/.claude/skills/citation-management/scripts/extract_metadata.py +569 -0
- scientific_writer/.claude/skills/citation-management/scripts/format_bibtex.py +349 -0
- scientific_writer/.claude/skills/citation-management/scripts/search_google_scholar.py +282 -0
- scientific_writer/.claude/skills/citation-management/scripts/search_pubmed.py +398 -0
- scientific_writer/.claude/skills/citation-management/scripts/validate_citations.py +497 -0
- scientific_writer/.claude/skills/clinical-reports/IMPLEMENTATION_SUMMARY.md +641 -0
- scientific_writer/.claude/skills/clinical-reports/README.md +236 -0
- scientific_writer/.claude/skills/clinical-reports/SKILL.md +1088 -0
- scientific_writer/.claude/skills/clinical-reports/assets/case_report_template.md +352 -0
- scientific_writer/.claude/skills/clinical-reports/assets/clinical_trial_csr_template.md +353 -0
- scientific_writer/.claude/skills/clinical-reports/assets/clinical_trial_sae_template.md +359 -0
- scientific_writer/.claude/skills/clinical-reports/assets/consult_note_template.md +305 -0
- scientific_writer/.claude/skills/clinical-reports/assets/discharge_summary_template.md +453 -0
- scientific_writer/.claude/skills/clinical-reports/assets/hipaa_compliance_checklist.md +395 -0
- scientific_writer/.claude/skills/clinical-reports/assets/history_physical_template.md +305 -0
- scientific_writer/.claude/skills/clinical-reports/assets/lab_report_template.md +309 -0
- scientific_writer/.claude/skills/clinical-reports/assets/pathology_report_template.md +249 -0
- scientific_writer/.claude/skills/clinical-reports/assets/quality_checklist.md +338 -0
- scientific_writer/.claude/skills/clinical-reports/assets/radiology_report_template.md +318 -0
- scientific_writer/.claude/skills/clinical-reports/assets/soap_note_template.md +253 -0
- scientific_writer/.claude/skills/clinical-reports/references/case_report_guidelines.md +570 -0
- scientific_writer/.claude/skills/clinical-reports/references/clinical_trial_reporting.md +693 -0
- scientific_writer/.claude/skills/clinical-reports/references/data_presentation.md +530 -0
- scientific_writer/.claude/skills/clinical-reports/references/diagnostic_reports_standards.md +629 -0
- scientific_writer/.claude/skills/clinical-reports/references/medical_terminology.md +588 -0
- scientific_writer/.claude/skills/clinical-reports/references/patient_documentation.md +744 -0
- scientific_writer/.claude/skills/clinical-reports/references/peer_review_standards.md +585 -0
- scientific_writer/.claude/skills/clinical-reports/references/regulatory_compliance.md +577 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/check_deidentification.py +346 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/compliance_checker.py +78 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/extract_clinical_data.py +102 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/format_adverse_events.py +103 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/generate_report_template.py +163 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/terminology_validator.py +133 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/validate_case_report.py +334 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/validate_trial_report.py +89 -0
- scientific_writer/.claude/skills/document-skills/docx/LICENSE.txt +30 -0
- scientific_writer/.claude/skills/document-skills/docx/SKILL.md +197 -0
- scientific_writer/.claude/skills/document-skills/docx/docx-js.md +350 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/pack.py +159 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/unpack.py +29 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validate.py +69 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/__init__.py +15 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/base.py +951 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/docx.py +274 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/pptx.py +315 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/redlining.py +279 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml.md +610 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/__init__.py +1 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/document.py +1276 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/templates/comments.xml +3 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsExtended.xml +3 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsIds.xml +3 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/templates/people.xml +3 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/utilities.py +374 -0
- scientific_writer/.claude/skills/document-skills/pdf/LICENSE.txt +30 -0
- scientific_writer/.claude/skills/document-skills/pdf/SKILL.md +294 -0
- scientific_writer/.claude/skills/document-skills/pdf/forms.md +205 -0
- scientific_writer/.claude/skills/document-skills/pdf/reference.md +612 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/check_bounding_boxes.py +70 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/check_fillable_fields.py +12 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/convert_pdf_to_images.py +35 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/create_validation_image.py +41 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/extract_form_field_info.py +152 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/fill_fillable_fields.py +114 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- scientific_writer/.claude/skills/document-skills/pptx/LICENSE.txt +30 -0
- scientific_writer/.claude/skills/document-skills/pptx/SKILL.md +484 -0
- scientific_writer/.claude/skills/document-skills/pptx/html2pptx.md +625 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/pack.py +159 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/unpack.py +29 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validate.py +69 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/base.py +951 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/docx.py +274 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml.md +427 -0
- scientific_writer/.claude/skills/document-skills/pptx/scripts/html2pptx.js +979 -0
- scientific_writer/.claude/skills/document-skills/pptx/scripts/inventory.py +1020 -0
- scientific_writer/.claude/skills/document-skills/pptx/scripts/rearrange.py +231 -0
- scientific_writer/.claude/skills/document-skills/pptx/scripts/replace.py +385 -0
- scientific_writer/.claude/skills/document-skills/pptx/scripts/thumbnail.py +450 -0
- scientific_writer/.claude/skills/document-skills/xlsx/LICENSE.txt +30 -0
- scientific_writer/.claude/skills/document-skills/xlsx/SKILL.md +289 -0
- scientific_writer/.claude/skills/document-skills/xlsx/recalc.py +178 -0
- scientific_writer/.claude/skills/hypothesis-generation/SKILL.md +155 -0
- scientific_writer/.claude/skills/hypothesis-generation/assets/hypothesis_output_template.md +302 -0
- scientific_writer/.claude/skills/hypothesis-generation/references/experimental_design_patterns.md +327 -0
- scientific_writer/.claude/skills/hypothesis-generation/references/hypothesis_quality_criteria.md +196 -0
- scientific_writer/.claude/skills/hypothesis-generation/references/literature_search_strategies.md +505 -0
- scientific_writer/.claude/skills/latex-posters/README.md +417 -0
- scientific_writer/.claude/skills/latex-posters/SKILL.md +919 -0
- scientific_writer/.claude/skills/latex-posters/assets/baposter_template.tex +257 -0
- scientific_writer/.claude/skills/latex-posters/assets/beamerposter_template.tex +244 -0
- scientific_writer/.claude/skills/latex-posters/assets/poster_quality_checklist.md +358 -0
- scientific_writer/.claude/skills/latex-posters/assets/tikzposter_template.tex +251 -0
- scientific_writer/.claude/skills/latex-posters/references/latex_poster_packages.md +745 -0
- scientific_writer/.claude/skills/latex-posters/references/poster_content_guide.md +748 -0
- scientific_writer/.claude/skills/latex-posters/references/poster_design_principles.md +806 -0
- scientific_writer/.claude/skills/latex-posters/references/poster_layout_design.md +900 -0
- scientific_writer/.claude/skills/latex-posters/scripts/review_poster.sh +214 -0
- scientific_writer/.claude/skills/literature-review/SKILL.md +546 -0
- scientific_writer/.claude/skills/literature-review/assets/review_template.md +412 -0
- scientific_writer/.claude/skills/literature-review/references/citation_styles.md +166 -0
- scientific_writer/.claude/skills/literature-review/references/database_strategies.md +381 -0
- scientific_writer/.claude/skills/literature-review/scripts/generate_pdf.py +176 -0
- scientific_writer/.claude/skills/literature-review/scripts/search_databases.py +303 -0
- scientific_writer/.claude/skills/literature-review/scripts/verify_citations.py +222 -0
- scientific_writer/.claude/skills/markitdown/INSTALLATION_GUIDE.md +318 -0
- scientific_writer/.claude/skills/markitdown/LICENSE.txt +22 -0
- scientific_writer/.claude/skills/markitdown/OPENROUTER_INTEGRATION.md +359 -0
- scientific_writer/.claude/skills/markitdown/QUICK_REFERENCE.md +309 -0
- scientific_writer/.claude/skills/markitdown/README.md +184 -0
- scientific_writer/.claude/skills/markitdown/SKILL.md +450 -0
- scientific_writer/.claude/skills/markitdown/SKILL_SUMMARY.md +307 -0
- scientific_writer/.claude/skills/markitdown/assets/example_usage.md +463 -0
- scientific_writer/.claude/skills/markitdown/references/api_reference.md +399 -0
- scientific_writer/.claude/skills/markitdown/references/file_formats.md +542 -0
- scientific_writer/.claude/skills/markitdown/scripts/batch_convert.py +228 -0
- scientific_writer/.claude/skills/markitdown/scripts/convert_literature.py +283 -0
- scientific_writer/.claude/skills/markitdown/scripts/convert_with_ai.py +243 -0
- scientific_writer/.claude/skills/paper-2-web/SKILL.md +455 -0
- scientific_writer/.claude/skills/paper-2-web/references/installation.md +141 -0
- scientific_writer/.claude/skills/paper-2-web/references/paper2poster.md +346 -0
- scientific_writer/.claude/skills/paper-2-web/references/paper2video.md +305 -0
- scientific_writer/.claude/skills/paper-2-web/references/paper2web.md +187 -0
- scientific_writer/.claude/skills/paper-2-web/references/usage_examples.md +436 -0
- scientific_writer/.claude/skills/peer-review/SKILL.md +375 -0
- scientific_writer/.claude/skills/peer-review/references/common_issues.md +552 -0
- scientific_writer/.claude/skills/peer-review/references/reporting_standards.md +290 -0
- scientific_writer/.claude/skills/research-grants/README.md +285 -0
- scientific_writer/.claude/skills/research-grants/SKILL.md +896 -0
- scientific_writer/.claude/skills/research-grants/assets/budget_justification_template.md +453 -0
- scientific_writer/.claude/skills/research-grants/assets/nih_specific_aims_template.md +166 -0
- scientific_writer/.claude/skills/research-grants/assets/nsf_project_summary_template.md +92 -0
- scientific_writer/.claude/skills/research-grants/references/broader_impacts.md +392 -0
- scientific_writer/.claude/skills/research-grants/references/darpa_guidelines.md +636 -0
- scientific_writer/.claude/skills/research-grants/references/doe_guidelines.md +586 -0
- scientific_writer/.claude/skills/research-grants/references/nih_guidelines.md +851 -0
- scientific_writer/.claude/skills/research-grants/references/nsf_guidelines.md +570 -0
- scientific_writer/.claude/skills/research-grants/references/specific_aims_guide.md +458 -0
- scientific_writer/.claude/skills/research-lookup/README.md +116 -0
- scientific_writer/.claude/skills/research-lookup/SKILL.md +443 -0
- scientific_writer/.claude/skills/research-lookup/examples.py +174 -0
- scientific_writer/.claude/skills/research-lookup/lookup.py +93 -0
- scientific_writer/.claude/skills/research-lookup/research_lookup.py +335 -0
- scientific_writer/.claude/skills/research-lookup/scripts/research_lookup.py +261 -0
- scientific_writer/.claude/skills/scholar-evaluation/SKILL.md +254 -0
- scientific_writer/.claude/skills/scholar-evaluation/references/evaluation_framework.md +663 -0
- scientific_writer/.claude/skills/scholar-evaluation/scripts/calculate_scores.py +378 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/SKILL.md +530 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/common_biases.md +364 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/evidence_hierarchy.md +484 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/experimental_design.md +496 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/logical_fallacies.md +478 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/scientific_method.md +169 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/statistical_pitfalls.md +506 -0
- scientific_writer/.claude/skills/scientific-schematics/SKILL.md +2035 -0
- scientific_writer/.claude/skills/scientific-schematics/assets/block_diagram_template.tex +199 -0
- scientific_writer/.claude/skills/scientific-schematics/assets/circuit_template.tex +159 -0
- scientific_writer/.claude/skills/scientific-schematics/assets/flowchart_template.tex +161 -0
- scientific_writer/.claude/skills/scientific-schematics/assets/pathway_template.tex +162 -0
- scientific_writer/.claude/skills/scientific-schematics/assets/tikz_styles.tex +422 -0
- scientific_writer/.claude/skills/scientific-schematics/references/best_practices.md +562 -0
- scientific_writer/.claude/skills/scientific-schematics/references/diagram_types.md +637 -0
- scientific_writer/.claude/skills/scientific-schematics/references/python_libraries.md +791 -0
- scientific_writer/.claude/skills/scientific-schematics/references/tikz_guide.md +734 -0
- scientific_writer/.claude/skills/scientific-schematics/scripts/circuit_generator.py +307 -0
- scientific_writer/.claude/skills/scientific-schematics/scripts/compile_tikz.py +292 -0
- scientific_writer/.claude/skills/scientific-schematics/scripts/generate_flowchart.py +281 -0
- scientific_writer/.claude/skills/scientific-schematics/scripts/pathway_diagram.py +406 -0
- scientific_writer/.claude/skills/scientific-writing/SKILL.md +443 -0
- scientific_writer/.claude/skills/scientific-writing/references/citation_styles.md +720 -0
- scientific_writer/.claude/skills/scientific-writing/references/figures_tables.md +806 -0
- scientific_writer/.claude/skills/scientific-writing/references/imrad_structure.md +658 -0
- scientific_writer/.claude/skills/scientific-writing/references/reporting_guidelines.md +748 -0
- scientific_writer/.claude/skills/scientific-writing/references/writing_principles.md +824 -0
- scientific_writer/.claude/skills/treatment-plans/README.md +483 -0
- scientific_writer/.claude/skills/treatment-plans/SKILL.md +817 -0
- scientific_writer/.claude/skills/treatment-plans/assets/chronic_disease_management_plan.tex +636 -0
- scientific_writer/.claude/skills/treatment-plans/assets/general_medical_treatment_plan.tex +616 -0
- scientific_writer/.claude/skills/treatment-plans/assets/mental_health_treatment_plan.tex +745 -0
- scientific_writer/.claude/skills/treatment-plans/assets/pain_management_plan.tex +770 -0
- scientific_writer/.claude/skills/treatment-plans/assets/perioperative_care_plan.tex +724 -0
- scientific_writer/.claude/skills/treatment-plans/assets/quality_checklist.md +471 -0
- scientific_writer/.claude/skills/treatment-plans/assets/rehabilitation_treatment_plan.tex +727 -0
- scientific_writer/.claude/skills/treatment-plans/references/goal_setting_frameworks.md +411 -0
- scientific_writer/.claude/skills/treatment-plans/references/intervention_guidelines.md +507 -0
- scientific_writer/.claude/skills/treatment-plans/references/regulatory_compliance.md +476 -0
- scientific_writer/.claude/skills/treatment-plans/references/specialty_specific_guidelines.md +607 -0
- scientific_writer/.claude/skills/treatment-plans/references/treatment_plan_standards.md +456 -0
- scientific_writer/.claude/skills/treatment-plans/scripts/check_completeness.py +318 -0
- scientific_writer/.claude/skills/treatment-plans/scripts/generate_template.py +244 -0
- scientific_writer/.claude/skills/treatment-plans/scripts/timeline_generator.py +369 -0
- scientific_writer/.claude/skills/treatment-plans/scripts/validate_treatment_plan.py +367 -0
- scientific_writer/.claude/skills/venue-templates/SKILL.md +590 -0
- scientific_writer/.claude/skills/venue-templates/assets/grants/nih_specific_aims.tex +235 -0
- scientific_writer/.claude/skills/venue-templates/assets/grants/nsf_proposal_template.tex +375 -0
- scientific_writer/.claude/skills/venue-templates/assets/journals/nature_article.tex +171 -0
- scientific_writer/.claude/skills/venue-templates/assets/journals/neurips_article.tex +283 -0
- scientific_writer/.claude/skills/venue-templates/assets/journals/plos_one.tex +317 -0
- scientific_writer/.claude/skills/venue-templates/assets/posters/beamerposter_academic.tex +311 -0
- scientific_writer/.claude/skills/venue-templates/references/conferences_formatting.md +564 -0
- scientific_writer/.claude/skills/venue-templates/references/grants_requirements.md +787 -0
- scientific_writer/.claude/skills/venue-templates/references/journals_formatting.md +486 -0
- scientific_writer/.claude/skills/venue-templates/references/posters_guidelines.md +628 -0
- scientific_writer/.claude/skills/venue-templates/scripts/customize_template.py +206 -0
- scientific_writer/.claude/skills/venue-templates/scripts/query_template.py +260 -0
- scientific_writer/.claude/skills/venue-templates/scripts/validate_format.py +255 -0
- scientific_writer/__init__.py +1 -1
- scientific_writer/api.py +9 -5
- scientific_writer/cli.py +9 -5
- scientific_writer/core.py +28 -5
- {scientific_writer-2.2.1.dist-info → scientific_writer-2.2.3.dist-info}/METADATA +1 -1
- scientific_writer-2.2.3.dist-info/RECORD +312 -0
- scientific_writer-2.2.1.dist-info/RECORD +0 -11
- {scientific_writer-2.2.1.dist-info → scientific_writer-2.2.3.dist-info}/WHEEL +0 -0
- {scientific_writer-2.2.1.dist-info → scientific_writer-2.2.3.dist-info}/entry_points.txt +0 -0
- {scientific_writer-2.2.1.dist-info → scientific_writer-2.2.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Interactive template generator for clinical reports.
|
|
4
|
+
|
|
5
|
+
Helps users select and generate appropriate clinical report templates.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
python generate_report_template.py
|
|
9
|
+
python generate_report_template.py --type case_report --output my_case_report.md
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
import shutil
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
TEMPLATES = {
|
|
18
|
+
"case_report": "case_report_template.md",
|
|
19
|
+
"soap_note": "soap_note_template.md",
|
|
20
|
+
"h_and_p": "history_physical_template.md",
|
|
21
|
+
"discharge_summary": "discharge_summary_template.md",
|
|
22
|
+
"consult_note": "consult_note_template.md",
|
|
23
|
+
"radiology": "radiology_report_template.md",
|
|
24
|
+
"pathology": "pathology_report_template.md",
|
|
25
|
+
"lab": "lab_report_template.md",
|
|
26
|
+
"sae": "clinical_trial_sae_template.md",
|
|
27
|
+
"csr": "clinical_trial_csr_template.md",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
DESCRIPTIONS = {
|
|
31
|
+
"case_report": "Clinical Case Report (CARE guidelines)",
|
|
32
|
+
"soap_note": "SOAP Progress Note",
|
|
33
|
+
"h_and_p": "History and Physical Examination",
|
|
34
|
+
"discharge_summary": "Hospital Discharge Summary",
|
|
35
|
+
"consult_note": "Consultation Note",
|
|
36
|
+
"radiology": "Radiology/Imaging Report",
|
|
37
|
+
"pathology": "Surgical Pathology Report",
|
|
38
|
+
"lab": "Laboratory Report",
|
|
39
|
+
"sae": "Serious Adverse Event Report",
|
|
40
|
+
"csr": "Clinical Study Report (ICH-E3)",
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def get_template_dir() -> Path:
|
|
45
|
+
"""Get the templates directory path."""
|
|
46
|
+
script_dir = Path(__file__).parent
|
|
47
|
+
template_dir = script_dir.parent / "assets"
|
|
48
|
+
return template_dir
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def list_templates():
|
|
52
|
+
"""List available templates."""
|
|
53
|
+
print("\nAvailable Clinical Report Templates:")
|
|
54
|
+
print("=" * 60)
|
|
55
|
+
for i, (key, desc) in enumerate(DESCRIPTIONS.items(), 1):
|
|
56
|
+
print(f"{i:2}. {key:20} - {desc}")
|
|
57
|
+
print("=" * 60)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def generate_template(template_type: str, output_file: str = None):
|
|
61
|
+
"""Generate template file."""
|
|
62
|
+
if template_type not in TEMPLATES:
|
|
63
|
+
raise ValueError(f"Invalid template type: {template_type}")
|
|
64
|
+
|
|
65
|
+
template_filename = TEMPLATES[template_type]
|
|
66
|
+
template_path = get_template_dir() / template_filename
|
|
67
|
+
|
|
68
|
+
if not template_path.exists():
|
|
69
|
+
raise FileNotFoundError(f"Template not found: {template_path}")
|
|
70
|
+
|
|
71
|
+
if output_file is None:
|
|
72
|
+
output_file = f"new_{template_filename}"
|
|
73
|
+
|
|
74
|
+
shutil.copy(template_path, output_file)
|
|
75
|
+
print(f"✓ Template created: {output_file}")
|
|
76
|
+
print(f" Type: {DESCRIPTIONS[template_type]}")
|
|
77
|
+
print(f" Source: {template_filename}")
|
|
78
|
+
|
|
79
|
+
return output_file
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def interactive_mode():
|
|
83
|
+
"""Interactive template selection."""
|
|
84
|
+
list_templates()
|
|
85
|
+
print()
|
|
86
|
+
|
|
87
|
+
while True:
|
|
88
|
+
choice = input("Select template number (or 'q' to quit): ").strip()
|
|
89
|
+
|
|
90
|
+
if choice.lower() == 'q':
|
|
91
|
+
print("Goodbye!")
|
|
92
|
+
return
|
|
93
|
+
|
|
94
|
+
try:
|
|
95
|
+
idx = int(choice) - 1
|
|
96
|
+
template_types = list(TEMPLATES.keys())
|
|
97
|
+
|
|
98
|
+
if 0 <= idx < len(template_types):
|
|
99
|
+
template_type = template_types[idx]
|
|
100
|
+
output_file = input(f"Output filename (default: new_{TEMPLATES[template_type]}): ").strip()
|
|
101
|
+
|
|
102
|
+
if not output_file:
|
|
103
|
+
output_file = None
|
|
104
|
+
|
|
105
|
+
generate_template(template_type, output_file)
|
|
106
|
+
|
|
107
|
+
another = input("\nGenerate another template? (y/n): ").strip().lower()
|
|
108
|
+
if another != 'y':
|
|
109
|
+
print("Goodbye!")
|
|
110
|
+
return
|
|
111
|
+
else:
|
|
112
|
+
print()
|
|
113
|
+
list_templates()
|
|
114
|
+
print()
|
|
115
|
+
else:
|
|
116
|
+
print("Invalid selection. Please try again.")
|
|
117
|
+
except (ValueError, IndexError):
|
|
118
|
+
print("Invalid input. Please enter a number or 'q' to quit.")
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def main():
|
|
122
|
+
"""Main entry point."""
|
|
123
|
+
parser = argparse.ArgumentParser(
|
|
124
|
+
description="Generate clinical report templates"
|
|
125
|
+
)
|
|
126
|
+
parser.add_argument(
|
|
127
|
+
"--type",
|
|
128
|
+
choices=list(TEMPLATES.keys()),
|
|
129
|
+
help="Template type to generate"
|
|
130
|
+
)
|
|
131
|
+
parser.add_argument(
|
|
132
|
+
"--output",
|
|
133
|
+
"-o",
|
|
134
|
+
help="Output filename"
|
|
135
|
+
)
|
|
136
|
+
parser.add_argument(
|
|
137
|
+
"--list",
|
|
138
|
+
action="store_true",
|
|
139
|
+
help="List available templates"
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
args = parser.parse_args()
|
|
143
|
+
|
|
144
|
+
try:
|
|
145
|
+
if args.list:
|
|
146
|
+
list_templates()
|
|
147
|
+
elif args.type:
|
|
148
|
+
generate_template(args.type, args.output)
|
|
149
|
+
else:
|
|
150
|
+
# Interactive mode
|
|
151
|
+
interactive_mode()
|
|
152
|
+
|
|
153
|
+
return 0
|
|
154
|
+
|
|
155
|
+
except Exception as e:
|
|
156
|
+
print(f"Error: {e}")
|
|
157
|
+
return 1
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
if __name__ == "__main__":
|
|
161
|
+
import sys
|
|
162
|
+
sys.exit(main())
|
|
163
|
+
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Validate medical terminology and coding in clinical reports.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
python terminology_validator.py <report_file>
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
import json
|
|
11
|
+
import re
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Common medical abbreviations that should be avoided (JCAHO "Do Not Use" list)
|
|
15
|
+
DO_NOT_USE = {
|
|
16
|
+
"U": "Unit",
|
|
17
|
+
"IU": "International Unit",
|
|
18
|
+
"QD": "daily",
|
|
19
|
+
"QOD": "every other day",
|
|
20
|
+
"MS": "morphine sulfate or magnesium sulfate",
|
|
21
|
+
"MSO4": "morphine sulfate",
|
|
22
|
+
"MgSO4": "magnesium sulfate",
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
# Common abbreviations with potential ambiguity
|
|
26
|
+
AMBIGUOUS = ["cc", "hs", "TIW", "SC", "SQ", "D/C", "AS", "AD", "AU", "OS", "OD", "OU"]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def check_do_not_use_abbreviations(content: str) -> dict:
|
|
30
|
+
"""Check for prohibited abbreviations."""
|
|
31
|
+
violations = {}
|
|
32
|
+
|
|
33
|
+
for abbrev, meaning in DO_NOT_USE.items():
|
|
34
|
+
# Word boundary pattern to avoid false positives
|
|
35
|
+
pattern = rf"\b{re.escape(abbrev)}\b"
|
|
36
|
+
matches = re.findall(pattern, content)
|
|
37
|
+
if matches:
|
|
38
|
+
violations[abbrev] = {
|
|
39
|
+
"count": len(matches),
|
|
40
|
+
"should_use": meaning,
|
|
41
|
+
"severity": "HIGH"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return violations
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def check_ambiguous_abbreviations(content: str) -> dict:
|
|
48
|
+
"""Check for ambiguous abbreviations."""
|
|
49
|
+
found = {}
|
|
50
|
+
|
|
51
|
+
for abbrev in AMBIGUOUS:
|
|
52
|
+
pattern = rf"\b{re.escape(abbrev)}\b"
|
|
53
|
+
matches = re.findall(pattern, content, re.IGNORECASE)
|
|
54
|
+
if matches:
|
|
55
|
+
found[abbrev] = {
|
|
56
|
+
"count": len(matches),
|
|
57
|
+
"severity": "MEDIUM"
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return found
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def validate_icd10_format(content: str) -> list:
|
|
64
|
+
"""Check ICD-10 code format."""
|
|
65
|
+
# ICD-10 format: Letter + 2 digits + optional decimal + 0-4 more digits
|
|
66
|
+
pattern = r"\b[A-Z]\d{2}\.?\d{0,4}\b"
|
|
67
|
+
codes = re.findall(pattern, content)
|
|
68
|
+
return list(set(codes)) # Unique codes
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def main():
|
|
72
|
+
"""Main entry point."""
|
|
73
|
+
parser = argparse.ArgumentParser(description="Validate medical terminology")
|
|
74
|
+
parser.add_argument("input_file", help="Path to clinical report")
|
|
75
|
+
parser.add_argument("--json", action="store_true")
|
|
76
|
+
|
|
77
|
+
args = parser.parse_args()
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
with open(args.input_file, 'r', encoding='utf-8') as f:
|
|
81
|
+
content = f.read()
|
|
82
|
+
|
|
83
|
+
do_not_use = check_do_not_use_abbreviations(content)
|
|
84
|
+
ambiguous = check_ambiguous_abbreviations(content)
|
|
85
|
+
icd10_codes = validate_icd10_format(content)
|
|
86
|
+
|
|
87
|
+
report = {
|
|
88
|
+
"filename": args.input_file,
|
|
89
|
+
"do_not_use_violations": do_not_use,
|
|
90
|
+
"ambiguous_abbreviations": ambiguous,
|
|
91
|
+
"icd10_codes_found": icd10_codes,
|
|
92
|
+
"total_issues": len(do_not_use) + len(ambiguous)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if args.json:
|
|
96
|
+
print(json.dumps(report, indent=2))
|
|
97
|
+
else:
|
|
98
|
+
print("\nTerminology Validation Report:\n")
|
|
99
|
+
|
|
100
|
+
if do_not_use:
|
|
101
|
+
print("❌ DO NOT USE Abbreviations Found:")
|
|
102
|
+
for abbrev, details in do_not_use.items():
|
|
103
|
+
print(f" {abbrev}: {details['count']} occurrence(s)")
|
|
104
|
+
print(f" → Use '{details['should_use']}' instead")
|
|
105
|
+
print()
|
|
106
|
+
else:
|
|
107
|
+
print("✓ No prohibited abbreviations found\n")
|
|
108
|
+
|
|
109
|
+
if ambiguous:
|
|
110
|
+
print("⚠ Ambiguous Abbreviations Found:")
|
|
111
|
+
for abbrev, details in ambiguous.items():
|
|
112
|
+
print(f" {abbrev}: {details['count']} occurrence(s)")
|
|
113
|
+
print(" Consider spelling out for clarity\n")
|
|
114
|
+
|
|
115
|
+
if icd10_codes:
|
|
116
|
+
print(f"ℹ ICD-10 codes detected: {len(icd10_codes)}")
|
|
117
|
+
for code in icd10_codes[:5]:
|
|
118
|
+
print(f" - {code}")
|
|
119
|
+
if len(icd10_codes) > 5:
|
|
120
|
+
print(f" ... and {len(icd10_codes) - 5} more")
|
|
121
|
+
print()
|
|
122
|
+
|
|
123
|
+
return 0 if not do_not_use else 1
|
|
124
|
+
|
|
125
|
+
except Exception as e:
|
|
126
|
+
print(f"Error: {e}")
|
|
127
|
+
return 1
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
if __name__ == "__main__":
|
|
131
|
+
import sys
|
|
132
|
+
sys.exit(main())
|
|
133
|
+
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Validate case reports against CARE (CAse REport) guidelines.
|
|
4
|
+
|
|
5
|
+
This script checks a clinical case report for compliance with CARE guidelines
|
|
6
|
+
and provides a checklist of required elements.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python validate_case_report.py <input_file.md|.txt>
|
|
10
|
+
python validate_case_report.py <input_file> --output report.json
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import argparse
|
|
14
|
+
import json
|
|
15
|
+
import re
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Dict, List, Tuple
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CareValidator:
|
|
21
|
+
"""Validator for CARE guideline compliance."""
|
|
22
|
+
|
|
23
|
+
# CARE checklist items with regex patterns
|
|
24
|
+
CARE_REQUIREMENTS = {
|
|
25
|
+
"title": {
|
|
26
|
+
"name": "Title contains 'case report'",
|
|
27
|
+
"pattern": r"(?i)(case\s+report|case\s+study)",
|
|
28
|
+
"section": "Title",
|
|
29
|
+
"required": True
|
|
30
|
+
},
|
|
31
|
+
"keywords": {
|
|
32
|
+
"name": "Keywords provided (2-5)",
|
|
33
|
+
"pattern": r"(?i)keywords?[:]\s*(.+)",
|
|
34
|
+
"section": "Keywords",
|
|
35
|
+
"required": True
|
|
36
|
+
},
|
|
37
|
+
"abstract": {
|
|
38
|
+
"name": "Abstract present",
|
|
39
|
+
"pattern": r"(?i)##?\s*abstract",
|
|
40
|
+
"section": "Abstract",
|
|
41
|
+
"required": True
|
|
42
|
+
},
|
|
43
|
+
"introduction": {
|
|
44
|
+
"name": "Introduction explaining novelty",
|
|
45
|
+
"pattern": r"(?i)##?\s*introduction",
|
|
46
|
+
"section": "Introduction",
|
|
47
|
+
"required": True
|
|
48
|
+
},
|
|
49
|
+
"patient_info": {
|
|
50
|
+
"name": "Patient demographics present",
|
|
51
|
+
"pattern": r"(?i)(patient\s+information|demographics?)",
|
|
52
|
+
"section": "Patient Information",
|
|
53
|
+
"required": True
|
|
54
|
+
},
|
|
55
|
+
"clinical_findings": {
|
|
56
|
+
"name": "Clinical findings documented",
|
|
57
|
+
"pattern": r"(?i)(clinical\s+findings?|physical\s+exam)",
|
|
58
|
+
"section": "Clinical Findings",
|
|
59
|
+
"required": True
|
|
60
|
+
},
|
|
61
|
+
"timeline": {
|
|
62
|
+
"name": "Timeline of events",
|
|
63
|
+
"pattern": r"(?i)(timeline|chronology)",
|
|
64
|
+
"section": "Timeline",
|
|
65
|
+
"required": True
|
|
66
|
+
},
|
|
67
|
+
"diagnostic": {
|
|
68
|
+
"name": "Diagnostic assessment",
|
|
69
|
+
"pattern": r"(?i)diagnostic\s+(assessment|evaluation|workup)",
|
|
70
|
+
"section": "Diagnostic Assessment",
|
|
71
|
+
"required": True
|
|
72
|
+
},
|
|
73
|
+
"therapeutic": {
|
|
74
|
+
"name": "Therapeutic interventions",
|
|
75
|
+
"pattern": r"(?i)(therapeutic\s+intervention|treatment)",
|
|
76
|
+
"section": "Therapeutic Interventions",
|
|
77
|
+
"required": True
|
|
78
|
+
},
|
|
79
|
+
"followup": {
|
|
80
|
+
"name": "Follow-up and outcomes",
|
|
81
|
+
"pattern": r"(?i)(follow[\-\s]?up|outcomes?)",
|
|
82
|
+
"section": "Follow-up and Outcomes",
|
|
83
|
+
"required": True
|
|
84
|
+
},
|
|
85
|
+
"discussion": {
|
|
86
|
+
"name": "Discussion with literature review",
|
|
87
|
+
"pattern": r"(?i)##?\s*discussion",
|
|
88
|
+
"section": "Discussion",
|
|
89
|
+
"required": True
|
|
90
|
+
},
|
|
91
|
+
"consent": {
|
|
92
|
+
"name": "Informed consent statement",
|
|
93
|
+
"pattern": r"(?i)(informed\s+consent|written\s+consent|consent.*obtained)",
|
|
94
|
+
"section": "Informed Consent",
|
|
95
|
+
"required": True
|
|
96
|
+
},
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# HIPAA identifiers to check for
|
|
100
|
+
HIPAA_PATTERNS = {
|
|
101
|
+
"dates": r"\b(0?[1-9]|1[0-2])/(0?[1-9]|[12][0-9]|3[01])/\d{4}\b",
|
|
102
|
+
"phone": r"\b\d{3}[-.]?\d{3}[-.]?\d{4}\b",
|
|
103
|
+
"email": r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b",
|
|
104
|
+
"ssn": r"\b\d{3}-\d{2}-\d{4}\b",
|
|
105
|
+
"mrn": r"(?i)(mrn|medical\s+record)[:]\s*\d+",
|
|
106
|
+
"zip_full": r"\b\d{5}-\d{4}\b",
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
def __init__(self, filename: str):
|
|
110
|
+
"""Initialize validator with input file."""
|
|
111
|
+
self.filename = Path(filename)
|
|
112
|
+
self.content = self._read_file()
|
|
113
|
+
self.results = {}
|
|
114
|
+
|
|
115
|
+
def _read_file(self) -> str:
|
|
116
|
+
"""Read input file content."""
|
|
117
|
+
try:
|
|
118
|
+
with open(self.filename, 'r', encoding='utf-8') as f:
|
|
119
|
+
return f.read()
|
|
120
|
+
except FileNotFoundError:
|
|
121
|
+
raise FileNotFoundError(f"File not found: {self.filename}")
|
|
122
|
+
except Exception as e:
|
|
123
|
+
raise Exception(f"Error reading file: {e}")
|
|
124
|
+
|
|
125
|
+
def validate_care_compliance(self) -> Dict[str, Dict]:
|
|
126
|
+
"""Validate compliance with CARE guidelines."""
|
|
127
|
+
results = {}
|
|
128
|
+
|
|
129
|
+
for key, item in self.CARE_REQUIREMENTS.items():
|
|
130
|
+
pattern = item["pattern"]
|
|
131
|
+
found = bool(re.search(pattern, self.content))
|
|
132
|
+
|
|
133
|
+
results[key] = {
|
|
134
|
+
"name": item["name"],
|
|
135
|
+
"section": item["section"],
|
|
136
|
+
"required": item["required"],
|
|
137
|
+
"found": found,
|
|
138
|
+
"status": "PASS" if found else "FAIL" if item["required"] else "WARNING"
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
self.results["care_compliance"] = results
|
|
142
|
+
return results
|
|
143
|
+
|
|
144
|
+
def check_deidentification(self) -> Dict[str, List[str]]:
|
|
145
|
+
"""Check for potential HIPAA identifier violations."""
|
|
146
|
+
violations = {}
|
|
147
|
+
|
|
148
|
+
for identifier, pattern in self.HIPAA_PATTERNS.items():
|
|
149
|
+
matches = re.findall(pattern, self.content)
|
|
150
|
+
if matches:
|
|
151
|
+
violations[identifier] = matches[:5] # Limit to first 5 examples
|
|
152
|
+
|
|
153
|
+
self.results["hipaa_violations"] = violations
|
|
154
|
+
return violations
|
|
155
|
+
|
|
156
|
+
def check_word_count(self) -> Dict[str, int]:
|
|
157
|
+
"""Check word count and provide limits guidance."""
|
|
158
|
+
words = len(re.findall(r'\b\w+\b', self.content))
|
|
159
|
+
|
|
160
|
+
word_count = {
|
|
161
|
+
"total_words": words,
|
|
162
|
+
"typical_min": 1500,
|
|
163
|
+
"typical_max": 3000,
|
|
164
|
+
"status": "ACCEPTABLE" if 1500 <= words <= 3500 else "CHECK"
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
self.results["word_count"] = word_count
|
|
168
|
+
return word_count
|
|
169
|
+
|
|
170
|
+
def check_references(self) -> Dict[str, any]:
|
|
171
|
+
"""Check for presence of references."""
|
|
172
|
+
ref_patterns = [
|
|
173
|
+
r"##?\s*references",
|
|
174
|
+
r"\[\d+\]",
|
|
175
|
+
r"\d+\.\s+[A-Z][a-z]+.*\d{4}", # Numbered references
|
|
176
|
+
]
|
|
177
|
+
|
|
178
|
+
has_refs = any(re.search(p, self.content, re.IGNORECASE) for p in ref_patterns)
|
|
179
|
+
ref_count = len(re.findall(r"\[\d+\]", self.content))
|
|
180
|
+
|
|
181
|
+
references = {
|
|
182
|
+
"has_references": has_refs,
|
|
183
|
+
"estimated_count": ref_count,
|
|
184
|
+
"recommended_min": 10,
|
|
185
|
+
"status": "ACCEPTABLE" if ref_count >= 10 else "LOW"
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
self.results["references"] = references
|
|
189
|
+
return references
|
|
190
|
+
|
|
191
|
+
def generate_report(self) -> Dict:
|
|
192
|
+
"""Generate comprehensive validation report."""
|
|
193
|
+
if not self.results:
|
|
194
|
+
self.validate_care_compliance()
|
|
195
|
+
self.check_deidentification()
|
|
196
|
+
self.check_word_count()
|
|
197
|
+
self.check_references()
|
|
198
|
+
|
|
199
|
+
# Calculate overall compliance
|
|
200
|
+
care = self.results["care_compliance"]
|
|
201
|
+
total_required = sum(1 for v in care.values() if v["required"])
|
|
202
|
+
passed = sum(1 for v in care.values() if v["required"] and v["found"])
|
|
203
|
+
compliance_rate = (passed / total_required * 100) if total_required > 0 else 0
|
|
204
|
+
|
|
205
|
+
report = {
|
|
206
|
+
"filename": str(self.filename),
|
|
207
|
+
"compliance_rate": round(compliance_rate, 1),
|
|
208
|
+
"care_compliance": care,
|
|
209
|
+
"hipaa_violations": self.results["hipaa_violations"],
|
|
210
|
+
"word_count": self.results["word_count"],
|
|
211
|
+
"references": self.results["references"],
|
|
212
|
+
"overall_status": "PASS" if compliance_rate >= 90 and not self.results["hipaa_violations"] else "NEEDS_REVISION"
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return report
|
|
216
|
+
|
|
217
|
+
def print_report(self):
|
|
218
|
+
"""Print human-readable validation report."""
|
|
219
|
+
report = self.generate_report()
|
|
220
|
+
|
|
221
|
+
print("=" * 70)
|
|
222
|
+
print(f"CARE Guideline Validation Report")
|
|
223
|
+
print(f"File: {report['filename']}")
|
|
224
|
+
print("=" * 70)
|
|
225
|
+
print()
|
|
226
|
+
|
|
227
|
+
print(f"Overall Compliance: {report['compliance_rate']}%")
|
|
228
|
+
print(f"Status: {report['overall_status']}")
|
|
229
|
+
print()
|
|
230
|
+
|
|
231
|
+
print("CARE Checklist:")
|
|
232
|
+
print("-" * 70)
|
|
233
|
+
for key, item in report["care_compliance"].items():
|
|
234
|
+
status_symbol = "✓" if item["found"] else "✗"
|
|
235
|
+
print(f"{status_symbol} [{item['status']:8}] {item['name']}")
|
|
236
|
+
print()
|
|
237
|
+
|
|
238
|
+
if report["hipaa_violations"]:
|
|
239
|
+
print("HIPAA DE-IDENTIFICATION WARNINGS:")
|
|
240
|
+
print("-" * 70)
|
|
241
|
+
for identifier, examples in report["hipaa_violations"].items():
|
|
242
|
+
print(f"⚠ {identifier.upper()}: {len(examples)} instance(s) found")
|
|
243
|
+
for ex in examples[:3]:
|
|
244
|
+
print(f" Example: {ex}")
|
|
245
|
+
print()
|
|
246
|
+
else:
|
|
247
|
+
print("✓ No obvious HIPAA identifiers detected")
|
|
248
|
+
print()
|
|
249
|
+
|
|
250
|
+
wc = report["word_count"]
|
|
251
|
+
print(f"Word Count: {wc['total_words']} words")
|
|
252
|
+
print(f" Typical range: {wc['typical_min']}-{wc['typical_max']} words")
|
|
253
|
+
print(f" Status: {wc['status']}")
|
|
254
|
+
print()
|
|
255
|
+
|
|
256
|
+
refs = report["references"]
|
|
257
|
+
print(f"References: {refs['estimated_count']} citation(s) detected")
|
|
258
|
+
print(f" Recommended minimum: {refs['recommended_min']}")
|
|
259
|
+
print(f" Status: {refs['status']}")
|
|
260
|
+
print()
|
|
261
|
+
|
|
262
|
+
print("=" * 70)
|
|
263
|
+
|
|
264
|
+
# Recommendations
|
|
265
|
+
issues = []
|
|
266
|
+
if report['compliance_rate'] < 100:
|
|
267
|
+
missing = [v["name"] for v in report["care_compliance"].values() if v["required"] and not v["found"]]
|
|
268
|
+
issues.append(f"Missing required sections: {', '.join(missing)}")
|
|
269
|
+
|
|
270
|
+
if report["hipaa_violations"]:
|
|
271
|
+
issues.append("HIPAA identifiers detected - review de-identification")
|
|
272
|
+
|
|
273
|
+
if refs["status"] == "LOW":
|
|
274
|
+
issues.append("Low reference count - consider adding more citations")
|
|
275
|
+
|
|
276
|
+
if issues:
|
|
277
|
+
print("RECOMMENDATIONS:")
|
|
278
|
+
for i, issue in enumerate(issues, 1):
|
|
279
|
+
print(f"{i}. {issue}")
|
|
280
|
+
else:
|
|
281
|
+
print("✓ Case report meets CARE guidelines!")
|
|
282
|
+
|
|
283
|
+
print("=" * 70)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def main():
|
|
287
|
+
"""Main entry point."""
|
|
288
|
+
parser = argparse.ArgumentParser(
|
|
289
|
+
description="Validate clinical case reports against CARE guidelines"
|
|
290
|
+
)
|
|
291
|
+
parser.add_argument(
|
|
292
|
+
"input_file",
|
|
293
|
+
help="Path to case report file (Markdown or text)"
|
|
294
|
+
)
|
|
295
|
+
parser.add_argument(
|
|
296
|
+
"--output",
|
|
297
|
+
"-o",
|
|
298
|
+
help="Output JSON report to file"
|
|
299
|
+
)
|
|
300
|
+
parser.add_argument(
|
|
301
|
+
"--json",
|
|
302
|
+
action="store_true",
|
|
303
|
+
help="Output JSON to stdout instead of human-readable report"
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
args = parser.parse_args()
|
|
307
|
+
|
|
308
|
+
try:
|
|
309
|
+
validator = CareValidator(args.input_file)
|
|
310
|
+
report = validator.generate_report()
|
|
311
|
+
|
|
312
|
+
if args.json:
|
|
313
|
+
print(json.dumps(report, indent=2))
|
|
314
|
+
else:
|
|
315
|
+
validator.print_report()
|
|
316
|
+
|
|
317
|
+
if args.output:
|
|
318
|
+
with open(args.output, 'w') as f:
|
|
319
|
+
json.dumps(report, f, indent=2)
|
|
320
|
+
print(f"\nJSON report saved to: {args.output}")
|
|
321
|
+
|
|
322
|
+
# Exit with non-zero if validation failed
|
|
323
|
+
exit_code = 0 if report["overall_status"] == "PASS" else 1
|
|
324
|
+
return exit_code
|
|
325
|
+
|
|
326
|
+
except Exception as e:
|
|
327
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
328
|
+
return 1
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
if __name__ == "__main__":
|
|
332
|
+
import sys
|
|
333
|
+
sys.exit(main())
|
|
334
|
+
|