scientific-writer 2.3.1__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.
Files changed (315) hide show
  1. scientific_writer/.claude/WRITER.md +822 -0
  2. scientific_writer/.claude/settings.local.json +30 -0
  3. scientific_writer/.claude/skills/citation-management/SKILL.md +1046 -0
  4. scientific_writer/.claude/skills/citation-management/assets/bibtex_template.bib +264 -0
  5. scientific_writer/.claude/skills/citation-management/assets/citation_checklist.md +386 -0
  6. scientific_writer/.claude/skills/citation-management/references/bibtex_formatting.md +908 -0
  7. scientific_writer/.claude/skills/citation-management/references/citation_validation.md +794 -0
  8. scientific_writer/.claude/skills/citation-management/references/google_scholar_search.md +725 -0
  9. scientific_writer/.claude/skills/citation-management/references/metadata_extraction.md +870 -0
  10. scientific_writer/.claude/skills/citation-management/references/pubmed_search.md +839 -0
  11. scientific_writer/.claude/skills/citation-management/scripts/doi_to_bibtex.py +204 -0
  12. scientific_writer/.claude/skills/citation-management/scripts/extract_metadata.py +569 -0
  13. scientific_writer/.claude/skills/citation-management/scripts/format_bibtex.py +349 -0
  14. scientific_writer/.claude/skills/citation-management/scripts/search_google_scholar.py +282 -0
  15. scientific_writer/.claude/skills/citation-management/scripts/search_pubmed.py +398 -0
  16. scientific_writer/.claude/skills/citation-management/scripts/validate_citations.py +497 -0
  17. scientific_writer/.claude/skills/clinical-reports/IMPLEMENTATION_SUMMARY.md +641 -0
  18. scientific_writer/.claude/skills/clinical-reports/README.md +236 -0
  19. scientific_writer/.claude/skills/clinical-reports/SKILL.md +1088 -0
  20. scientific_writer/.claude/skills/clinical-reports/assets/case_report_template.md +352 -0
  21. scientific_writer/.claude/skills/clinical-reports/assets/clinical_trial_csr_template.md +353 -0
  22. scientific_writer/.claude/skills/clinical-reports/assets/clinical_trial_sae_template.md +359 -0
  23. scientific_writer/.claude/skills/clinical-reports/assets/consult_note_template.md +305 -0
  24. scientific_writer/.claude/skills/clinical-reports/assets/discharge_summary_template.md +453 -0
  25. scientific_writer/.claude/skills/clinical-reports/assets/hipaa_compliance_checklist.md +395 -0
  26. scientific_writer/.claude/skills/clinical-reports/assets/history_physical_template.md +305 -0
  27. scientific_writer/.claude/skills/clinical-reports/assets/lab_report_template.md +309 -0
  28. scientific_writer/.claude/skills/clinical-reports/assets/pathology_report_template.md +249 -0
  29. scientific_writer/.claude/skills/clinical-reports/assets/quality_checklist.md +338 -0
  30. scientific_writer/.claude/skills/clinical-reports/assets/radiology_report_template.md +318 -0
  31. scientific_writer/.claude/skills/clinical-reports/assets/soap_note_template.md +253 -0
  32. scientific_writer/.claude/skills/clinical-reports/references/case_report_guidelines.md +570 -0
  33. scientific_writer/.claude/skills/clinical-reports/references/clinical_trial_reporting.md +693 -0
  34. scientific_writer/.claude/skills/clinical-reports/references/data_presentation.md +530 -0
  35. scientific_writer/.claude/skills/clinical-reports/references/diagnostic_reports_standards.md +629 -0
  36. scientific_writer/.claude/skills/clinical-reports/references/medical_terminology.md +588 -0
  37. scientific_writer/.claude/skills/clinical-reports/references/patient_documentation.md +744 -0
  38. scientific_writer/.claude/skills/clinical-reports/references/peer_review_standards.md +585 -0
  39. scientific_writer/.claude/skills/clinical-reports/references/regulatory_compliance.md +577 -0
  40. scientific_writer/.claude/skills/clinical-reports/scripts/check_deidentification.py +346 -0
  41. scientific_writer/.claude/skills/clinical-reports/scripts/compliance_checker.py +78 -0
  42. scientific_writer/.claude/skills/clinical-reports/scripts/extract_clinical_data.py +102 -0
  43. scientific_writer/.claude/skills/clinical-reports/scripts/format_adverse_events.py +103 -0
  44. scientific_writer/.claude/skills/clinical-reports/scripts/generate_report_template.py +163 -0
  45. scientific_writer/.claude/skills/clinical-reports/scripts/terminology_validator.py +133 -0
  46. scientific_writer/.claude/skills/clinical-reports/scripts/validate_case_report.py +334 -0
  47. scientific_writer/.claude/skills/clinical-reports/scripts/validate_trial_report.py +89 -0
  48. scientific_writer/.claude/skills/document-skills/docx/LICENSE.txt +30 -0
  49. scientific_writer/.claude/skills/document-skills/docx/SKILL.md +197 -0
  50. scientific_writer/.claude/skills/document-skills/docx/docx-js.md +350 -0
  51. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  52. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  53. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  54. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  55. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  56. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  57. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  58. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  59. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  60. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  61. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  62. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  63. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  64. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  65. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  66. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  67. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  68. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  69. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  70. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  71. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  72. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  73. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  74. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  75. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  76. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  77. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  78. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  79. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  80. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  81. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  82. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
  83. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  84. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  85. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  86. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  87. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  88. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  89. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  90. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/pack.py +159 -0
  91. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/unpack.py +29 -0
  92. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validate.py +69 -0
  93. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/__init__.py +15 -0
  94. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/base.py +951 -0
  95. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/docx.py +274 -0
  96. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/pptx.py +315 -0
  97. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/redlining.py +279 -0
  98. scientific_writer/.claude/skills/document-skills/docx/ooxml.md +610 -0
  99. scientific_writer/.claude/skills/document-skills/docx/scripts/__init__.py +1 -0
  100. scientific_writer/.claude/skills/document-skills/docx/scripts/document.py +1276 -0
  101. scientific_writer/.claude/skills/document-skills/docx/scripts/templates/comments.xml +3 -0
  102. scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsExtended.xml +3 -0
  103. scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  104. scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsIds.xml +3 -0
  105. scientific_writer/.claude/skills/document-skills/docx/scripts/templates/people.xml +3 -0
  106. scientific_writer/.claude/skills/document-skills/docx/scripts/utilities.py +374 -0
  107. scientific_writer/.claude/skills/document-skills/pdf/LICENSE.txt +30 -0
  108. scientific_writer/.claude/skills/document-skills/pdf/SKILL.md +294 -0
  109. scientific_writer/.claude/skills/document-skills/pdf/forms.md +205 -0
  110. scientific_writer/.claude/skills/document-skills/pdf/reference.md +612 -0
  111. scientific_writer/.claude/skills/document-skills/pdf/scripts/check_bounding_boxes.py +70 -0
  112. scientific_writer/.claude/skills/document-skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  113. scientific_writer/.claude/skills/document-skills/pdf/scripts/check_fillable_fields.py +12 -0
  114. scientific_writer/.claude/skills/document-skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  115. scientific_writer/.claude/skills/document-skills/pdf/scripts/create_validation_image.py +41 -0
  116. scientific_writer/.claude/skills/document-skills/pdf/scripts/extract_form_field_info.py +152 -0
  117. scientific_writer/.claude/skills/document-skills/pdf/scripts/fill_fillable_fields.py +114 -0
  118. scientific_writer/.claude/skills/document-skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  119. scientific_writer/.claude/skills/document-skills/pptx/LICENSE.txt +30 -0
  120. scientific_writer/.claude/skills/document-skills/pptx/SKILL.md +484 -0
  121. scientific_writer/.claude/skills/document-skills/pptx/html2pptx.md +625 -0
  122. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  123. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  124. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  125. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  126. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  127. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  128. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  129. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  130. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  131. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  132. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  133. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  134. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  135. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  136. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  137. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  138. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  139. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  140. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  141. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  142. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  143. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  144. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  145. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  146. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  147. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  148. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  149. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  150. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  151. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  152. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  153. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  154. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  155. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  156. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  157. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  158. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  159. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  160. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  161. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/pack.py +159 -0
  162. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/unpack.py +29 -0
  163. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validate.py +69 -0
  164. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
  165. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/base.py +951 -0
  166. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/docx.py +274 -0
  167. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
  168. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
  169. scientific_writer/.claude/skills/document-skills/pptx/ooxml.md +427 -0
  170. scientific_writer/.claude/skills/document-skills/pptx/scripts/html2pptx.js +979 -0
  171. scientific_writer/.claude/skills/document-skills/pptx/scripts/inventory.py +1020 -0
  172. scientific_writer/.claude/skills/document-skills/pptx/scripts/rearrange.py +231 -0
  173. scientific_writer/.claude/skills/document-skills/pptx/scripts/replace.py +385 -0
  174. scientific_writer/.claude/skills/document-skills/pptx/scripts/thumbnail.py +450 -0
  175. scientific_writer/.claude/skills/document-skills/xlsx/LICENSE.txt +30 -0
  176. scientific_writer/.claude/skills/document-skills/xlsx/SKILL.md +289 -0
  177. scientific_writer/.claude/skills/document-skills/xlsx/recalc.py +178 -0
  178. scientific_writer/.claude/skills/hypothesis-generation/SKILL.md +155 -0
  179. scientific_writer/.claude/skills/hypothesis-generation/assets/hypothesis_output_template.md +302 -0
  180. scientific_writer/.claude/skills/hypothesis-generation/references/experimental_design_patterns.md +327 -0
  181. scientific_writer/.claude/skills/hypothesis-generation/references/hypothesis_quality_criteria.md +196 -0
  182. scientific_writer/.claude/skills/hypothesis-generation/references/literature_search_strategies.md +505 -0
  183. scientific_writer/.claude/skills/latex-posters/README.md +417 -0
  184. scientific_writer/.claude/skills/latex-posters/SKILL.md +919 -0
  185. scientific_writer/.claude/skills/latex-posters/assets/baposter_template.tex +257 -0
  186. scientific_writer/.claude/skills/latex-posters/assets/beamerposter_template.tex +244 -0
  187. scientific_writer/.claude/skills/latex-posters/assets/poster_quality_checklist.md +358 -0
  188. scientific_writer/.claude/skills/latex-posters/assets/tikzposter_template.tex +251 -0
  189. scientific_writer/.claude/skills/latex-posters/references/latex_poster_packages.md +745 -0
  190. scientific_writer/.claude/skills/latex-posters/references/poster_content_guide.md +748 -0
  191. scientific_writer/.claude/skills/latex-posters/references/poster_design_principles.md +806 -0
  192. scientific_writer/.claude/skills/latex-posters/references/poster_layout_design.md +900 -0
  193. scientific_writer/.claude/skills/latex-posters/scripts/review_poster.sh +214 -0
  194. scientific_writer/.claude/skills/literature-review/SKILL.md +546 -0
  195. scientific_writer/.claude/skills/literature-review/assets/review_template.md +412 -0
  196. scientific_writer/.claude/skills/literature-review/references/citation_styles.md +166 -0
  197. scientific_writer/.claude/skills/literature-review/references/database_strategies.md +381 -0
  198. scientific_writer/.claude/skills/literature-review/scripts/generate_pdf.py +176 -0
  199. scientific_writer/.claude/skills/literature-review/scripts/search_databases.py +303 -0
  200. scientific_writer/.claude/skills/literature-review/scripts/verify_citations.py +222 -0
  201. scientific_writer/.claude/skills/markitdown/INSTALLATION_GUIDE.md +318 -0
  202. scientific_writer/.claude/skills/markitdown/LICENSE.txt +22 -0
  203. scientific_writer/.claude/skills/markitdown/OPENROUTER_INTEGRATION.md +359 -0
  204. scientific_writer/.claude/skills/markitdown/QUICK_REFERENCE.md +309 -0
  205. scientific_writer/.claude/skills/markitdown/README.md +184 -0
  206. scientific_writer/.claude/skills/markitdown/SKILL.md +450 -0
  207. scientific_writer/.claude/skills/markitdown/SKILL_SUMMARY.md +307 -0
  208. scientific_writer/.claude/skills/markitdown/assets/example_usage.md +463 -0
  209. scientific_writer/.claude/skills/markitdown/references/api_reference.md +399 -0
  210. scientific_writer/.claude/skills/markitdown/references/file_formats.md +542 -0
  211. scientific_writer/.claude/skills/markitdown/scripts/batch_convert.py +228 -0
  212. scientific_writer/.claude/skills/markitdown/scripts/convert_literature.py +283 -0
  213. scientific_writer/.claude/skills/markitdown/scripts/convert_with_ai.py +243 -0
  214. scientific_writer/.claude/skills/paper-2-web/SKILL.md +455 -0
  215. scientific_writer/.claude/skills/paper-2-web/references/installation.md +141 -0
  216. scientific_writer/.claude/skills/paper-2-web/references/paper2poster.md +346 -0
  217. scientific_writer/.claude/skills/paper-2-web/references/paper2video.md +305 -0
  218. scientific_writer/.claude/skills/paper-2-web/references/paper2web.md +187 -0
  219. scientific_writer/.claude/skills/paper-2-web/references/usage_examples.md +436 -0
  220. scientific_writer/.claude/skills/peer-review/SKILL.md +375 -0
  221. scientific_writer/.claude/skills/peer-review/references/common_issues.md +552 -0
  222. scientific_writer/.claude/skills/peer-review/references/reporting_standards.md +290 -0
  223. scientific_writer/.claude/skills/research-grants/README.md +285 -0
  224. scientific_writer/.claude/skills/research-grants/SKILL.md +896 -0
  225. scientific_writer/.claude/skills/research-grants/assets/budget_justification_template.md +453 -0
  226. scientific_writer/.claude/skills/research-grants/assets/nih_specific_aims_template.md +166 -0
  227. scientific_writer/.claude/skills/research-grants/assets/nsf_project_summary_template.md +92 -0
  228. scientific_writer/.claude/skills/research-grants/references/broader_impacts.md +392 -0
  229. scientific_writer/.claude/skills/research-grants/references/darpa_guidelines.md +636 -0
  230. scientific_writer/.claude/skills/research-grants/references/doe_guidelines.md +586 -0
  231. scientific_writer/.claude/skills/research-grants/references/nih_guidelines.md +851 -0
  232. scientific_writer/.claude/skills/research-grants/references/nsf_guidelines.md +570 -0
  233. scientific_writer/.claude/skills/research-grants/references/specific_aims_guide.md +458 -0
  234. scientific_writer/.claude/skills/research-lookup/README.md +116 -0
  235. scientific_writer/.claude/skills/research-lookup/SKILL.md +443 -0
  236. scientific_writer/.claude/skills/research-lookup/examples.py +174 -0
  237. scientific_writer/.claude/skills/research-lookup/lookup.py +93 -0
  238. scientific_writer/.claude/skills/research-lookup/research_lookup.py +335 -0
  239. scientific_writer/.claude/skills/research-lookup/scripts/research_lookup.py +261 -0
  240. scientific_writer/.claude/skills/scholar-evaluation/SKILL.md +254 -0
  241. scientific_writer/.claude/skills/scholar-evaluation/references/evaluation_framework.md +663 -0
  242. scientific_writer/.claude/skills/scholar-evaluation/scripts/calculate_scores.py +378 -0
  243. scientific_writer/.claude/skills/scientific-critical-thinking/SKILL.md +530 -0
  244. scientific_writer/.claude/skills/scientific-critical-thinking/references/common_biases.md +364 -0
  245. scientific_writer/.claude/skills/scientific-critical-thinking/references/evidence_hierarchy.md +484 -0
  246. scientific_writer/.claude/skills/scientific-critical-thinking/references/experimental_design.md +496 -0
  247. scientific_writer/.claude/skills/scientific-critical-thinking/references/logical_fallacies.md +478 -0
  248. scientific_writer/.claude/skills/scientific-critical-thinking/references/scientific_method.md +169 -0
  249. scientific_writer/.claude/skills/scientific-critical-thinking/references/statistical_pitfalls.md +506 -0
  250. scientific_writer/.claude/skills/scientific-schematics/SKILL.md +2035 -0
  251. scientific_writer/.claude/skills/scientific-schematics/assets/block_diagram_template.tex +199 -0
  252. scientific_writer/.claude/skills/scientific-schematics/assets/circuit_template.tex +159 -0
  253. scientific_writer/.claude/skills/scientific-schematics/assets/flowchart_template.tex +161 -0
  254. scientific_writer/.claude/skills/scientific-schematics/assets/pathway_template.tex +162 -0
  255. scientific_writer/.claude/skills/scientific-schematics/assets/tikz_styles.tex +422 -0
  256. scientific_writer/.claude/skills/scientific-schematics/references/best_practices.md +562 -0
  257. scientific_writer/.claude/skills/scientific-schematics/references/diagram_types.md +637 -0
  258. scientific_writer/.claude/skills/scientific-schematics/references/python_libraries.md +791 -0
  259. scientific_writer/.claude/skills/scientific-schematics/references/tikz_guide.md +734 -0
  260. scientific_writer/.claude/skills/scientific-schematics/scripts/circuit_generator.py +307 -0
  261. scientific_writer/.claude/skills/scientific-schematics/scripts/compile_tikz.py +292 -0
  262. scientific_writer/.claude/skills/scientific-schematics/scripts/generate_flowchart.py +281 -0
  263. scientific_writer/.claude/skills/scientific-schematics/scripts/pathway_diagram.py +406 -0
  264. scientific_writer/.claude/skills/scientific-writing/SKILL.md +443 -0
  265. scientific_writer/.claude/skills/scientific-writing/references/citation_styles.md +720 -0
  266. scientific_writer/.claude/skills/scientific-writing/references/figures_tables.md +806 -0
  267. scientific_writer/.claude/skills/scientific-writing/references/imrad_structure.md +658 -0
  268. scientific_writer/.claude/skills/scientific-writing/references/reporting_guidelines.md +748 -0
  269. scientific_writer/.claude/skills/scientific-writing/references/writing_principles.md +824 -0
  270. scientific_writer/.claude/skills/treatment-plans/README.md +488 -0
  271. scientific_writer/.claude/skills/treatment-plans/SKILL.md +1536 -0
  272. scientific_writer/.claude/skills/treatment-plans/assets/STYLING_QUICK_REFERENCE.md +185 -0
  273. scientific_writer/.claude/skills/treatment-plans/assets/chronic_disease_management_plan.tex +665 -0
  274. scientific_writer/.claude/skills/treatment-plans/assets/general_medical_treatment_plan.tex +547 -0
  275. scientific_writer/.claude/skills/treatment-plans/assets/medical_treatment_plan.sty +222 -0
  276. scientific_writer/.claude/skills/treatment-plans/assets/mental_health_treatment_plan.tex +774 -0
  277. scientific_writer/.claude/skills/treatment-plans/assets/one_page_treatment_plan.tex +193 -0
  278. scientific_writer/.claude/skills/treatment-plans/assets/pain_management_plan.tex +799 -0
  279. scientific_writer/.claude/skills/treatment-plans/assets/perioperative_care_plan.tex +753 -0
  280. scientific_writer/.claude/skills/treatment-plans/assets/quality_checklist.md +471 -0
  281. scientific_writer/.claude/skills/treatment-plans/assets/rehabilitation_treatment_plan.tex +756 -0
  282. scientific_writer/.claude/skills/treatment-plans/references/goal_setting_frameworks.md +411 -0
  283. scientific_writer/.claude/skills/treatment-plans/references/intervention_guidelines.md +507 -0
  284. scientific_writer/.claude/skills/treatment-plans/references/regulatory_compliance.md +476 -0
  285. scientific_writer/.claude/skills/treatment-plans/references/specialty_specific_guidelines.md +655 -0
  286. scientific_writer/.claude/skills/treatment-plans/references/treatment_plan_standards.md +485 -0
  287. scientific_writer/.claude/skills/treatment-plans/scripts/check_completeness.py +318 -0
  288. scientific_writer/.claude/skills/treatment-plans/scripts/generate_template.py +244 -0
  289. scientific_writer/.claude/skills/treatment-plans/scripts/timeline_generator.py +369 -0
  290. scientific_writer/.claude/skills/treatment-plans/scripts/validate_treatment_plan.py +367 -0
  291. scientific_writer/.claude/skills/venue-templates/SKILL.md +590 -0
  292. scientific_writer/.claude/skills/venue-templates/assets/grants/nih_specific_aims.tex +235 -0
  293. scientific_writer/.claude/skills/venue-templates/assets/grants/nsf_proposal_template.tex +375 -0
  294. scientific_writer/.claude/skills/venue-templates/assets/journals/nature_article.tex +171 -0
  295. scientific_writer/.claude/skills/venue-templates/assets/journals/neurips_article.tex +283 -0
  296. scientific_writer/.claude/skills/venue-templates/assets/journals/plos_one.tex +317 -0
  297. scientific_writer/.claude/skills/venue-templates/assets/posters/beamerposter_academic.tex +311 -0
  298. scientific_writer/.claude/skills/venue-templates/references/conferences_formatting.md +564 -0
  299. scientific_writer/.claude/skills/venue-templates/references/grants_requirements.md +787 -0
  300. scientific_writer/.claude/skills/venue-templates/references/journals_formatting.md +486 -0
  301. scientific_writer/.claude/skills/venue-templates/references/posters_guidelines.md +628 -0
  302. scientific_writer/.claude/skills/venue-templates/scripts/customize_template.py +206 -0
  303. scientific_writer/.claude/skills/venue-templates/scripts/query_template.py +260 -0
  304. scientific_writer/.claude/skills/venue-templates/scripts/validate_format.py +255 -0
  305. scientific_writer/__init__.py +43 -0
  306. scientific_writer/api.py +393 -0
  307. scientific_writer/cli.py +326 -0
  308. scientific_writer/core.py +275 -0
  309. scientific_writer/models.py +76 -0
  310. scientific_writer/utils.py +289 -0
  311. scientific_writer-2.3.1.dist-info/METADATA +272 -0
  312. scientific_writer-2.3.1.dist-info/RECORD +315 -0
  313. scientific_writer-2.3.1.dist-info/WHEEL +4 -0
  314. scientific_writer-2.3.1.dist-info/entry_points.txt +2 -0
  315. scientific_writer-2.3.1.dist-info/licenses/LICENSE +22 -0
@@ -0,0 +1,349 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ BibTeX Formatter and Cleaner
4
+ Format, clean, sort, and deduplicate BibTeX files.
5
+ """
6
+
7
+ import sys
8
+ import re
9
+ import argparse
10
+ from typing import List, Dict, Tuple
11
+ from collections import OrderedDict
12
+
13
+ class BibTeXFormatter:
14
+ """Format and clean BibTeX entries."""
15
+
16
+ def __init__(self):
17
+ # Standard field order for readability
18
+ self.field_order = [
19
+ 'author', 'editor', 'title', 'booktitle', 'journal',
20
+ 'year', 'month', 'volume', 'number', 'pages',
21
+ 'publisher', 'address', 'edition', 'series',
22
+ 'school', 'institution', 'organization',
23
+ 'howpublished', 'doi', 'url', 'isbn', 'issn',
24
+ 'note', 'abstract', 'keywords'
25
+ ]
26
+
27
+ def parse_bibtex_file(self, filepath: str) -> List[Dict]:
28
+ """
29
+ Parse BibTeX file and extract entries.
30
+
31
+ Args:
32
+ filepath: Path to BibTeX file
33
+
34
+ Returns:
35
+ List of entry dictionaries
36
+ """
37
+ try:
38
+ with open(filepath, 'r', encoding='utf-8') as f:
39
+ content = f.read()
40
+ except Exception as e:
41
+ print(f'Error reading file: {e}', file=sys.stderr)
42
+ return []
43
+
44
+ entries = []
45
+
46
+ # Match BibTeX entries
47
+ pattern = r'@(\w+)\s*\{\s*([^,\s]+)\s*,(.*?)\n\}'
48
+ matches = re.finditer(pattern, content, re.DOTALL | re.IGNORECASE)
49
+
50
+ for match in matches:
51
+ entry_type = match.group(1).lower()
52
+ citation_key = match.group(2).strip()
53
+ fields_text = match.group(3)
54
+
55
+ # Parse fields
56
+ fields = OrderedDict()
57
+ field_pattern = r'(\w+)\s*=\s*\{([^}]*)\}|(\w+)\s*=\s*"([^"]*)"'
58
+ field_matches = re.finditer(field_pattern, fields_text)
59
+
60
+ for field_match in field_matches:
61
+ if field_match.group(1):
62
+ field_name = field_match.group(1).lower()
63
+ field_value = field_match.group(2)
64
+ else:
65
+ field_name = field_match.group(3).lower()
66
+ field_value = field_match.group(4)
67
+
68
+ fields[field_name] = field_value.strip()
69
+
70
+ entries.append({
71
+ 'type': entry_type,
72
+ 'key': citation_key,
73
+ 'fields': fields
74
+ })
75
+
76
+ return entries
77
+
78
+ def format_entry(self, entry: Dict) -> str:
79
+ """
80
+ Format a single BibTeX entry.
81
+
82
+ Args:
83
+ entry: Entry dictionary
84
+
85
+ Returns:
86
+ Formatted BibTeX string
87
+ """
88
+ lines = [f'@{entry["type"]}{{{entry["key"]},']
89
+
90
+ # Order fields according to standard order
91
+ ordered_fields = OrderedDict()
92
+
93
+ # Add fields in standard order
94
+ for field_name in self.field_order:
95
+ if field_name in entry['fields']:
96
+ ordered_fields[field_name] = entry['fields'][field_name]
97
+
98
+ # Add any remaining fields
99
+ for field_name, field_value in entry['fields'].items():
100
+ if field_name not in ordered_fields:
101
+ ordered_fields[field_name] = field_value
102
+
103
+ # Format each field
104
+ max_field_len = max(len(f) for f in ordered_fields.keys()) if ordered_fields else 0
105
+
106
+ for field_name, field_value in ordered_fields.items():
107
+ # Pad field name for alignment
108
+ padded_field = field_name.ljust(max_field_len)
109
+ lines.append(f' {padded_field} = {{{field_value}}},')
110
+
111
+ # Remove trailing comma from last field
112
+ if lines[-1].endswith(','):
113
+ lines[-1] = lines[-1][:-1]
114
+
115
+ lines.append('}')
116
+
117
+ return '\n'.join(lines)
118
+
119
+ def fix_common_issues(self, entry: Dict) -> Dict:
120
+ """
121
+ Fix common formatting issues in entry.
122
+
123
+ Args:
124
+ entry: Entry dictionary
125
+
126
+ Returns:
127
+ Fixed entry dictionary
128
+ """
129
+ fixed = entry.copy()
130
+ fields = fixed['fields'].copy()
131
+
132
+ # Fix page ranges (single hyphen to double hyphen)
133
+ if 'pages' in fields:
134
+ pages = fields['pages']
135
+ # Replace single hyphen with double hyphen if it's a range
136
+ if re.search(r'\d-\d', pages) and '--' not in pages:
137
+ pages = re.sub(r'(\d)-(\d)', r'\1--\2', pages)
138
+ fields['pages'] = pages
139
+
140
+ # Remove "pp." from pages
141
+ if 'pages' in fields:
142
+ pages = fields['pages']
143
+ pages = re.sub(r'^pp\.\s*', '', pages, flags=re.IGNORECASE)
144
+ fields['pages'] = pages
145
+
146
+ # Fix DOI (remove URL prefix if present)
147
+ if 'doi' in fields:
148
+ doi = fields['doi']
149
+ doi = doi.replace('https://doi.org/', '')
150
+ doi = doi.replace('http://doi.org/', '')
151
+ doi = doi.replace('doi:', '')
152
+ fields['doi'] = doi
153
+
154
+ # Fix author separators (semicolon or ampersand to 'and')
155
+ if 'author' in fields:
156
+ author = fields['author']
157
+ author = author.replace(';', ' and')
158
+ author = author.replace(' & ', ' and ')
159
+ # Clean up multiple 'and's
160
+ author = re.sub(r'\s+and\s+and\s+', ' and ', author)
161
+ fields['author'] = author
162
+
163
+ fixed['fields'] = fields
164
+ return fixed
165
+
166
+ def deduplicate_entries(self, entries: List[Dict]) -> List[Dict]:
167
+ """
168
+ Remove duplicate entries based on DOI or citation key.
169
+
170
+ Args:
171
+ entries: List of entry dictionaries
172
+
173
+ Returns:
174
+ List of unique entries
175
+ """
176
+ seen_dois = set()
177
+ seen_keys = set()
178
+ unique_entries = []
179
+
180
+ for entry in entries:
181
+ doi = entry['fields'].get('doi', '').strip()
182
+ key = entry['key']
183
+
184
+ # Check DOI first (more reliable)
185
+ if doi:
186
+ if doi in seen_dois:
187
+ print(f'Duplicate DOI found: {doi} (skipping {key})', file=sys.stderr)
188
+ continue
189
+ seen_dois.add(doi)
190
+
191
+ # Check citation key
192
+ if key in seen_keys:
193
+ print(f'Duplicate citation key found: {key} (skipping)', file=sys.stderr)
194
+ continue
195
+ seen_keys.add(key)
196
+
197
+ unique_entries.append(entry)
198
+
199
+ return unique_entries
200
+
201
+ def sort_entries(self, entries: List[Dict], sort_by: str = 'key', descending: bool = False) -> List[Dict]:
202
+ """
203
+ Sort entries by specified field.
204
+
205
+ Args:
206
+ entries: List of entry dictionaries
207
+ sort_by: Field to sort by ('key', 'year', 'author', 'title')
208
+ descending: Sort in descending order
209
+
210
+ Returns:
211
+ Sorted list of entries
212
+ """
213
+ def get_sort_key(entry: Dict) -> str:
214
+ if sort_by == 'key':
215
+ return entry['key'].lower()
216
+ elif sort_by == 'year':
217
+ year = entry['fields'].get('year', '9999')
218
+ return year
219
+ elif sort_by == 'author':
220
+ author = entry['fields'].get('author', 'ZZZ')
221
+ # Get last name of first author
222
+ if ',' in author:
223
+ return author.split(',')[0].lower()
224
+ else:
225
+ return author.split()[0].lower() if author else 'zzz'
226
+ elif sort_by == 'title':
227
+ return entry['fields'].get('title', '').lower()
228
+ else:
229
+ return entry['key'].lower()
230
+
231
+ return sorted(entries, key=get_sort_key, reverse=descending)
232
+
233
+ def format_file(self, filepath: str, output: str = None,
234
+ deduplicate: bool = False, sort_by: str = None,
235
+ descending: bool = False, fix_issues: bool = True) -> None:
236
+ """
237
+ Format entire BibTeX file.
238
+
239
+ Args:
240
+ filepath: Input BibTeX file
241
+ output: Output file (None for in-place)
242
+ deduplicate: Remove duplicates
243
+ sort_by: Field to sort by
244
+ descending: Sort in descending order
245
+ fix_issues: Fix common formatting issues
246
+ """
247
+ print(f'Parsing {filepath}...', file=sys.stderr)
248
+ entries = self.parse_bibtex_file(filepath)
249
+
250
+ if not entries:
251
+ print('No entries found', file=sys.stderr)
252
+ return
253
+
254
+ print(f'Found {len(entries)} entries', file=sys.stderr)
255
+
256
+ # Fix common issues
257
+ if fix_issues:
258
+ print('Fixing common issues...', file=sys.stderr)
259
+ entries = [self.fix_common_issues(e) for e in entries]
260
+
261
+ # Deduplicate
262
+ if deduplicate:
263
+ print('Removing duplicates...', file=sys.stderr)
264
+ original_count = len(entries)
265
+ entries = self.deduplicate_entries(entries)
266
+ removed = original_count - len(entries)
267
+ if removed > 0:
268
+ print(f'Removed {removed} duplicate(s)', file=sys.stderr)
269
+
270
+ # Sort
271
+ if sort_by:
272
+ print(f'Sorting by {sort_by}...', file=sys.stderr)
273
+ entries = self.sort_entries(entries, sort_by, descending)
274
+
275
+ # Format entries
276
+ print('Formatting entries...', file=sys.stderr)
277
+ formatted_entries = [self.format_entry(e) for e in entries]
278
+
279
+ # Write output
280
+ output_content = '\n\n'.join(formatted_entries) + '\n'
281
+
282
+ output_file = output or filepath
283
+ try:
284
+ with open(output_file, 'w', encoding='utf-8') as f:
285
+ f.write(output_content)
286
+ print(f'Successfully wrote {len(entries)} entries to {output_file}', file=sys.stderr)
287
+ except Exception as e:
288
+ print(f'Error writing file: {e}', file=sys.stderr)
289
+ sys.exit(1)
290
+
291
+
292
+ def main():
293
+ """Command-line interface."""
294
+ parser = argparse.ArgumentParser(
295
+ description='Format, clean, sort, and deduplicate BibTeX files',
296
+ epilog='Example: python format_bibtex.py references.bib --deduplicate --sort year'
297
+ )
298
+
299
+ parser.add_argument(
300
+ 'file',
301
+ help='BibTeX file to format'
302
+ )
303
+
304
+ parser.add_argument(
305
+ '-o', '--output',
306
+ help='Output file (default: overwrite input file)'
307
+ )
308
+
309
+ parser.add_argument(
310
+ '--deduplicate',
311
+ action='store_true',
312
+ help='Remove duplicate entries'
313
+ )
314
+
315
+ parser.add_argument(
316
+ '--sort',
317
+ choices=['key', 'year', 'author', 'title'],
318
+ help='Sort entries by field'
319
+ )
320
+
321
+ parser.add_argument(
322
+ '--descending',
323
+ action='store_true',
324
+ help='Sort in descending order'
325
+ )
326
+
327
+ parser.add_argument(
328
+ '--no-fix',
329
+ action='store_true',
330
+ help='Do not fix common issues'
331
+ )
332
+
333
+ args = parser.parse_args()
334
+
335
+ # Format file
336
+ formatter = BibTeXFormatter()
337
+ formatter.format_file(
338
+ args.file,
339
+ output=args.output,
340
+ deduplicate=args.deduplicate,
341
+ sort_by=args.sort,
342
+ descending=args.descending,
343
+ fix_issues=not args.no_fix
344
+ )
345
+
346
+
347
+ if __name__ == '__main__':
348
+ main()
349
+
@@ -0,0 +1,282 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Google Scholar Search Tool
4
+ Search Google Scholar and export results.
5
+
6
+ Note: This script requires the 'scholarly' library.
7
+ Install with: pip install scholarly
8
+ """
9
+
10
+ import sys
11
+ import argparse
12
+ import json
13
+ import time
14
+ import random
15
+ from typing import List, Dict, Optional
16
+
17
+ try:
18
+ from scholarly import scholarly, ProxyGenerator
19
+ SCHOLARLY_AVAILABLE = True
20
+ except ImportError:
21
+ SCHOLARLY_AVAILABLE = False
22
+ print('Warning: scholarly library not installed. Install with: pip install scholarly', file=sys.stderr)
23
+
24
+ class GoogleScholarSearcher:
25
+ """Search Google Scholar using scholarly library."""
26
+
27
+ def __init__(self, use_proxy: bool = False):
28
+ """
29
+ Initialize searcher.
30
+
31
+ Args:
32
+ use_proxy: Use free proxy (helps avoid rate limiting)
33
+ """
34
+ if not SCHOLARLY_AVAILABLE:
35
+ raise ImportError('scholarly library required. Install with: pip install scholarly')
36
+
37
+ # Setup proxy if requested
38
+ if use_proxy:
39
+ try:
40
+ pg = ProxyGenerator()
41
+ pg.FreeProxies()
42
+ scholarly.use_proxy(pg)
43
+ print('Using free proxy', file=sys.stderr)
44
+ except Exception as e:
45
+ print(f'Warning: Could not setup proxy: {e}', file=sys.stderr)
46
+
47
+ def search(self, query: str, max_results: int = 50,
48
+ year_start: Optional[int] = None, year_end: Optional[int] = None,
49
+ sort_by: str = 'relevance') -> List[Dict]:
50
+ """
51
+ Search Google Scholar.
52
+
53
+ Args:
54
+ query: Search query
55
+ max_results: Maximum number of results
56
+ year_start: Start year filter
57
+ year_end: End year filter
58
+ sort_by: Sort order ('relevance' or 'citations')
59
+
60
+ Returns:
61
+ List of result dictionaries
62
+ """
63
+ if not SCHOLARLY_AVAILABLE:
64
+ print('Error: scholarly library not installed', file=sys.stderr)
65
+ return []
66
+
67
+ print(f'Searching Google Scholar: {query}', file=sys.stderr)
68
+ print(f'Max results: {max_results}', file=sys.stderr)
69
+
70
+ results = []
71
+
72
+ try:
73
+ # Perform search
74
+ search_query = scholarly.search_pubs(query)
75
+
76
+ for i, result in enumerate(search_query):
77
+ if i >= max_results:
78
+ break
79
+
80
+ print(f'Retrieved {i+1}/{max_results}', file=sys.stderr)
81
+
82
+ # Extract metadata
83
+ metadata = {
84
+ 'title': result.get('bib', {}).get('title', ''),
85
+ 'authors': ', '.join(result.get('bib', {}).get('author', [])),
86
+ 'year': result.get('bib', {}).get('pub_year', ''),
87
+ 'venue': result.get('bib', {}).get('venue', ''),
88
+ 'abstract': result.get('bib', {}).get('abstract', ''),
89
+ 'citations': result.get('num_citations', 0),
90
+ 'url': result.get('pub_url', ''),
91
+ 'eprint_url': result.get('eprint_url', ''),
92
+ }
93
+
94
+ # Filter by year
95
+ if year_start or year_end:
96
+ try:
97
+ pub_year = int(metadata['year']) if metadata['year'] else 0
98
+ if year_start and pub_year < year_start:
99
+ continue
100
+ if year_end and pub_year > year_end:
101
+ continue
102
+ except ValueError:
103
+ pass
104
+
105
+ results.append(metadata)
106
+
107
+ # Rate limiting to avoid blocking
108
+ time.sleep(random.uniform(2, 5))
109
+
110
+ except Exception as e:
111
+ print(f'Error during search: {e}', file=sys.stderr)
112
+
113
+ # Sort if requested
114
+ if sort_by == 'citations' and results:
115
+ results.sort(key=lambda x: x.get('citations', 0), reverse=True)
116
+
117
+ return results
118
+
119
+ def metadata_to_bibtex(self, metadata: Dict) -> str:
120
+ """Convert metadata to BibTeX format."""
121
+ # Generate citation key
122
+ if metadata.get('authors'):
123
+ first_author = metadata['authors'].split(',')[0].strip()
124
+ last_name = first_author.split()[-1] if first_author else 'Unknown'
125
+ else:
126
+ last_name = 'Unknown'
127
+
128
+ year = metadata.get('year', 'XXXX')
129
+
130
+ # Get keyword from title
131
+ import re
132
+ title = metadata.get('title', '')
133
+ words = re.findall(r'\b[a-zA-Z]{4,}\b', title)
134
+ keyword = words[0].lower() if words else 'paper'
135
+
136
+ citation_key = f'{last_name}{year}{keyword}'
137
+
138
+ # Determine entry type (guess based on venue)
139
+ venue = metadata.get('venue', '').lower()
140
+ if 'proceedings' in venue or 'conference' in venue:
141
+ entry_type = 'inproceedings'
142
+ venue_field = 'booktitle'
143
+ else:
144
+ entry_type = 'article'
145
+ venue_field = 'journal'
146
+
147
+ # Build BibTeX
148
+ lines = [f'@{entry_type}{{{citation_key},']
149
+
150
+ # Convert authors format
151
+ if metadata.get('authors'):
152
+ authors = metadata['authors'].replace(',', ' and')
153
+ lines.append(f' author = {{{authors}}},')
154
+
155
+ if metadata.get('title'):
156
+ lines.append(f' title = {{{metadata["title"]}}},')
157
+
158
+ if metadata.get('venue'):
159
+ lines.append(f' {venue_field} = {{{metadata["venue"]}}},')
160
+
161
+ if metadata.get('year'):
162
+ lines.append(f' year = {{{metadata["year"]}}},')
163
+
164
+ if metadata.get('url'):
165
+ lines.append(f' url = {{{metadata["url"]}}},')
166
+
167
+ if metadata.get('citations'):
168
+ lines.append(f' note = {{Cited by: {metadata["citations"]}}},')
169
+
170
+ # Remove trailing comma
171
+ if lines[-1].endswith(','):
172
+ lines[-1] = lines[-1][:-1]
173
+
174
+ lines.append('}')
175
+
176
+ return '\n'.join(lines)
177
+
178
+
179
+ def main():
180
+ """Command-line interface."""
181
+ parser = argparse.ArgumentParser(
182
+ description='Search Google Scholar (requires scholarly library)',
183
+ epilog='Example: python search_google_scholar.py "machine learning" --limit 50'
184
+ )
185
+
186
+ parser.add_argument(
187
+ 'query',
188
+ help='Search query'
189
+ )
190
+
191
+ parser.add_argument(
192
+ '--limit',
193
+ type=int,
194
+ default=50,
195
+ help='Maximum number of results (default: 50)'
196
+ )
197
+
198
+ parser.add_argument(
199
+ '--year-start',
200
+ type=int,
201
+ help='Start year for filtering'
202
+ )
203
+
204
+ parser.add_argument(
205
+ '--year-end',
206
+ type=int,
207
+ help='End year for filtering'
208
+ )
209
+
210
+ parser.add_argument(
211
+ '--sort-by',
212
+ choices=['relevance', 'citations'],
213
+ default='relevance',
214
+ help='Sort order (default: relevance)'
215
+ )
216
+
217
+ parser.add_argument(
218
+ '--use-proxy',
219
+ action='store_true',
220
+ help='Use free proxy to avoid rate limiting'
221
+ )
222
+
223
+ parser.add_argument(
224
+ '-o', '--output',
225
+ help='Output file (default: stdout)'
226
+ )
227
+
228
+ parser.add_argument(
229
+ '--format',
230
+ choices=['json', 'bibtex'],
231
+ default='json',
232
+ help='Output format (default: json)'
233
+ )
234
+
235
+ args = parser.parse_args()
236
+
237
+ if not SCHOLARLY_AVAILABLE:
238
+ print('\nError: scholarly library not installed', file=sys.stderr)
239
+ print('Install with: pip install scholarly', file=sys.stderr)
240
+ print('\nAlternatively, use PubMed search for biomedical literature:', file=sys.stderr)
241
+ print(' python search_pubmed.py "your query"', file=sys.stderr)
242
+ sys.exit(1)
243
+
244
+ # Search
245
+ searcher = GoogleScholarSearcher(use_proxy=args.use_proxy)
246
+ results = searcher.search(
247
+ args.query,
248
+ max_results=args.limit,
249
+ year_start=args.year_start,
250
+ year_end=args.year_end,
251
+ sort_by=args.sort_by
252
+ )
253
+
254
+ if not results:
255
+ print('No results found', file=sys.stderr)
256
+ sys.exit(1)
257
+
258
+ # Format output
259
+ if args.format == 'json':
260
+ output = json.dumps({
261
+ 'query': args.query,
262
+ 'count': len(results),
263
+ 'results': results
264
+ }, indent=2)
265
+ else: # bibtex
266
+ bibtex_entries = [searcher.metadata_to_bibtex(r) for r in results]
267
+ output = '\n\n'.join(bibtex_entries) + '\n'
268
+
269
+ # Write output
270
+ if args.output:
271
+ with open(args.output, 'w', encoding='utf-8') as f:
272
+ f.write(output)
273
+ print(f'Wrote {len(results)} results to {args.output}', file=sys.stderr)
274
+ else:
275
+ print(output)
276
+
277
+ print(f'\nRetrieved {len(results)} results', file=sys.stderr)
278
+
279
+
280
+ if __name__ == '__main__':
281
+ main()
282
+