@synsci/cli-darwin-x64 1.1.70 → 1.1.72
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.
- package/bin/skills/citation-management/SKILL.md +1109 -0
- package/bin/skills/citation-management/assets/bibtex_template.bib +264 -0
- package/bin/skills/citation-management/assets/citation_checklist.md +386 -0
- package/bin/skills/citation-management/references/bibtex_formatting.md +908 -0
- package/bin/skills/citation-management/references/citation_validation.md +794 -0
- package/bin/skills/citation-management/references/google_scholar_search.md +725 -0
- package/bin/skills/citation-management/references/metadata_extraction.md +870 -0
- package/bin/skills/citation-management/references/pubmed_search.md +839 -0
- package/bin/skills/citation-management/scripts/doi_to_bibtex.py +182 -0
- package/bin/skills/citation-management/scripts/extract_metadata.py +570 -0
- package/bin/skills/citation-management/scripts/format_bibtex.py +349 -0
- package/bin/skills/citation-management/scripts/search_google_scholar.py +251 -0
- package/bin/skills/citation-management/scripts/search_pubmed.py +348 -0
- package/bin/skills/citation-management/scripts/validate_citations.py +494 -0
- package/bin/skills/clinical-decision-support/README.md +129 -0
- package/bin/skills/clinical-decision-support/SKILL.md +506 -0
- package/bin/skills/clinical-decision-support/assets/biomarker_report_template.tex +380 -0
- package/bin/skills/clinical-decision-support/assets/clinical_pathway_template.tex +222 -0
- package/bin/skills/clinical-decision-support/assets/cohort_analysis_template.tex +359 -0
- package/bin/skills/clinical-decision-support/assets/color_schemes.tex +149 -0
- package/bin/skills/clinical-decision-support/assets/example_gbm_cohort.md +208 -0
- package/bin/skills/clinical-decision-support/assets/recommendation_strength_guide.md +328 -0
- package/bin/skills/clinical-decision-support/assets/treatment_recommendation_template.tex +529 -0
- package/bin/skills/clinical-decision-support/references/biomarker_classification.md +719 -0
- package/bin/skills/clinical-decision-support/references/clinical_decision_algorithms.md +604 -0
- package/bin/skills/clinical-decision-support/references/evidence_synthesis.md +840 -0
- package/bin/skills/clinical-decision-support/references/outcome_analysis.md +640 -0
- package/bin/skills/clinical-decision-support/references/patient_cohort_analysis.md +427 -0
- package/bin/skills/clinical-decision-support/references/treatment_recommendations.md +521 -0
- package/bin/skills/clinical-decision-support/scripts/biomarker_classifier.py +383 -0
- package/bin/skills/clinical-decision-support/scripts/build_decision_tree.py +417 -0
- package/bin/skills/clinical-decision-support/scripts/create_cohort_tables.py +509 -0
- package/bin/skills/clinical-decision-support/scripts/generate_survival_analysis.py +441 -0
- package/bin/skills/clinical-decision-support/scripts/validate_cds_document.py +326 -0
- package/bin/skills/clinical-reports/IMPLEMENTATION_SUMMARY.md +641 -0
- package/bin/skills/clinical-reports/README.md +236 -0
- package/bin/skills/clinical-reports/SKILL.md +1127 -0
- package/bin/skills/clinical-reports/assets/case_report_template.md +352 -0
- package/bin/skills/clinical-reports/assets/clinical_trial_csr_template.md +353 -0
- package/bin/skills/clinical-reports/assets/clinical_trial_sae_template.md +359 -0
- package/bin/skills/clinical-reports/assets/consult_note_template.md +305 -0
- package/bin/skills/clinical-reports/assets/discharge_summary_template.md +453 -0
- package/bin/skills/clinical-reports/assets/hipaa_compliance_checklist.md +395 -0
- package/bin/skills/clinical-reports/assets/history_physical_template.md +305 -0
- package/bin/skills/clinical-reports/assets/lab_report_template.md +309 -0
- package/bin/skills/clinical-reports/assets/pathology_report_template.md +249 -0
- package/bin/skills/clinical-reports/assets/quality_checklist.md +338 -0
- package/bin/skills/clinical-reports/assets/radiology_report_template.md +318 -0
- package/bin/skills/clinical-reports/assets/soap_note_template.md +253 -0
- package/bin/skills/clinical-reports/references/case_report_guidelines.md +570 -0
- package/bin/skills/clinical-reports/references/clinical_trial_reporting.md +693 -0
- package/bin/skills/clinical-reports/references/data_presentation.md +530 -0
- package/bin/skills/clinical-reports/references/diagnostic_reports_standards.md +629 -0
- package/bin/skills/clinical-reports/references/medical_terminology.md +588 -0
- package/bin/skills/clinical-reports/references/patient_documentation.md +744 -0
- package/bin/skills/clinical-reports/references/peer_review_standards.md +585 -0
- package/bin/skills/clinical-reports/references/regulatory_compliance.md +577 -0
- package/bin/skills/clinical-reports/scripts/check_deidentification.py +332 -0
- package/bin/skills/clinical-reports/scripts/compliance_checker.py +78 -0
- package/bin/skills/clinical-reports/scripts/extract_clinical_data.py +97 -0
- package/bin/skills/clinical-reports/scripts/format_adverse_events.py +97 -0
- package/bin/skills/clinical-reports/scripts/generate_report_template.py +149 -0
- package/bin/skills/clinical-reports/scripts/terminology_validator.py +126 -0
- package/bin/skills/clinical-reports/scripts/validate_case_report.py +323 -0
- package/bin/skills/clinical-reports/scripts/validate_trial_report.py +88 -0
- package/bin/skills/fireworks-ai/SKILL.md +665 -0
- package/bin/skills/generate-image/SKILL.md +178 -0
- package/bin/skills/generate-image/scripts/generate_image.py +254 -0
- package/bin/skills/groq/SKILL.md +347 -0
- package/bin/skills/hypothesis-generation/SKILL.md +293 -0
- package/bin/skills/hypothesis-generation/assets/FORMATTING_GUIDE.md +672 -0
- package/bin/skills/hypothesis-generation/assets/hypothesis_generation.sty +307 -0
- package/bin/skills/hypothesis-generation/assets/hypothesis_report_template.tex +572 -0
- package/bin/skills/hypothesis-generation/references/experimental_design_patterns.md +329 -0
- package/bin/skills/hypothesis-generation/references/hypothesis_quality_criteria.md +198 -0
- package/bin/skills/hypothesis-generation/references/literature_search_strategies.md +622 -0
- package/bin/skills/latex-posters/README.md +417 -0
- package/bin/skills/latex-posters/SKILL.md +1602 -0
- package/bin/skills/latex-posters/assets/baposter_template.tex +257 -0
- package/bin/skills/latex-posters/assets/beamerposter_template.tex +244 -0
- package/bin/skills/latex-posters/assets/poster_quality_checklist.md +358 -0
- package/bin/skills/latex-posters/assets/tikzposter_template.tex +251 -0
- package/bin/skills/latex-posters/references/latex_poster_packages.md +745 -0
- package/bin/skills/latex-posters/references/poster_content_guide.md +748 -0
- package/bin/skills/latex-posters/references/poster_design_principles.md +806 -0
- package/bin/skills/latex-posters/references/poster_layout_design.md +900 -0
- package/bin/skills/latex-posters/scripts/review_poster.sh +214 -0
- package/bin/skills/literature-review/SKILL.md +641 -0
- package/bin/skills/literature-review/assets/review_template.md +412 -0
- package/bin/skills/literature-review/references/citation_styles.md +166 -0
- package/bin/skills/literature-review/references/database_strategies.md +455 -0
- package/bin/skills/literature-review/scripts/generate_pdf.py +184 -0
- package/bin/skills/literature-review/scripts/search_databases.py +310 -0
- package/bin/skills/literature-review/scripts/verify_citations.py +218 -0
- package/bin/skills/market-research-reports/SKILL.md +904 -0
- package/bin/skills/market-research-reports/assets/FORMATTING_GUIDE.md +428 -0
- package/bin/skills/market-research-reports/assets/market_report_template.tex +1380 -0
- package/bin/skills/market-research-reports/assets/market_research.sty +564 -0
- package/bin/skills/market-research-reports/references/data_analysis_patterns.md +548 -0
- package/bin/skills/market-research-reports/references/report_structure_guide.md +999 -0
- package/bin/skills/market-research-reports/references/visual_generation_guide.md +1077 -0
- package/bin/skills/market-research-reports/scripts/generate_market_visuals.py +472 -0
- package/bin/skills/markitdown/INSTALLATION_GUIDE.md +318 -0
- package/bin/skills/markitdown/LICENSE.txt +22 -0
- package/bin/skills/markitdown/OPENROUTER_INTEGRATION.md +359 -0
- package/bin/skills/markitdown/QUICK_REFERENCE.md +309 -0
- package/bin/skills/markitdown/README.md +184 -0
- package/bin/skills/markitdown/SKILL.md +486 -0
- package/bin/skills/markitdown/SKILL_SUMMARY.md +307 -0
- package/bin/skills/markitdown/assets/example_usage.md +463 -0
- package/bin/skills/markitdown/references/api_reference.md +399 -0
- package/bin/skills/markitdown/references/file_formats.md +542 -0
- package/bin/skills/markitdown/scripts/batch_convert.py +195 -0
- package/bin/skills/markitdown/scripts/convert_literature.py +262 -0
- package/bin/skills/markitdown/scripts/convert_with_ai.py +224 -0
- package/bin/skills/ml-paper-writing/SKILL.md +937 -0
- package/bin/skills/ml-paper-writing/references/checklists.md +361 -0
- package/bin/skills/ml-paper-writing/references/citation-workflow.md +562 -0
- package/bin/skills/ml-paper-writing/references/reviewer-guidelines.md +367 -0
- package/bin/skills/ml-paper-writing/references/sources.md +159 -0
- package/bin/skills/ml-paper-writing/references/writing-guide.md +476 -0
- package/bin/skills/ml-paper-writing/templates/README.md +251 -0
- package/bin/skills/ml-paper-writing/templates/aaai2026/README.md +534 -0
- package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026-unified-supp.tex +144 -0
- package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026-unified-template.tex +952 -0
- package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026.bib +111 -0
- package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026.bst +1493 -0
- package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026.sty +315 -0
- package/bin/skills/ml-paper-writing/templates/acl/README.md +50 -0
- package/bin/skills/ml-paper-writing/templates/acl/acl.sty +312 -0
- package/bin/skills/ml-paper-writing/templates/acl/acl_latex.tex +377 -0
- package/bin/skills/ml-paper-writing/templates/acl/acl_lualatex.tex +101 -0
- package/bin/skills/ml-paper-writing/templates/acl/acl_natbib.bst +1940 -0
- package/bin/skills/ml-paper-writing/templates/acl/anthology.bib.txt +26 -0
- package/bin/skills/ml-paper-writing/templates/acl/custom.bib +70 -0
- package/bin/skills/ml-paper-writing/templates/acl/formatting.md +326 -0
- package/bin/skills/ml-paper-writing/templates/colm2025/README.md +3 -0
- package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.bib +11 -0
- package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.bst +1440 -0
- package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.pdf +0 -0
- package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.sty +218 -0
- package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.tex +305 -0
- package/bin/skills/ml-paper-writing/templates/colm2025/fancyhdr.sty +485 -0
- package/bin/skills/ml-paper-writing/templates/colm2025/math_commands.tex +508 -0
- package/bin/skills/ml-paper-writing/templates/colm2025/natbib.sty +1246 -0
- package/bin/skills/ml-paper-writing/templates/iclr2026/fancyhdr.sty +485 -0
- package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.bib +24 -0
- package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.bst +1440 -0
- package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.pdf +0 -0
- package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.sty +246 -0
- package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.tex +414 -0
- package/bin/skills/ml-paper-writing/templates/iclr2026/math_commands.tex +508 -0
- package/bin/skills/ml-paper-writing/templates/iclr2026/natbib.sty +1246 -0
- package/bin/skills/ml-paper-writing/templates/icml2026/algorithm.sty +79 -0
- package/bin/skills/ml-paper-writing/templates/icml2026/algorithmic.sty +201 -0
- package/bin/skills/ml-paper-writing/templates/icml2026/example_paper.bib +75 -0
- package/bin/skills/ml-paper-writing/templates/icml2026/example_paper.pdf +0 -0
- package/bin/skills/ml-paper-writing/templates/icml2026/example_paper.tex +662 -0
- package/bin/skills/ml-paper-writing/templates/icml2026/fancyhdr.sty +864 -0
- package/bin/skills/ml-paper-writing/templates/icml2026/icml2026.bst +1443 -0
- package/bin/skills/ml-paper-writing/templates/icml2026/icml2026.sty +767 -0
- package/bin/skills/ml-paper-writing/templates/icml2026/icml_numpapers.pdf +0 -0
- package/bin/skills/ml-paper-writing/templates/neurips2025/Makefile +36 -0
- package/bin/skills/ml-paper-writing/templates/neurips2025/extra_pkgs.tex +53 -0
- package/bin/skills/ml-paper-writing/templates/neurips2025/main.tex +38 -0
- package/bin/skills/ml-paper-writing/templates/neurips2025/neurips.sty +382 -0
- package/bin/skills/paper-2-web/SKILL.md +491 -0
- package/bin/skills/paper-2-web/references/installation.md +141 -0
- package/bin/skills/paper-2-web/references/paper2poster.md +346 -0
- package/bin/skills/paper-2-web/references/paper2video.md +305 -0
- package/bin/skills/paper-2-web/references/paper2web.md +187 -0
- package/bin/skills/paper-2-web/references/usage_examples.md +436 -0
- package/bin/skills/peer-review/SKILL.md +702 -0
- package/bin/skills/peer-review/references/calibration_guidelines.md +196 -0
- package/bin/skills/peer-review/references/common_issues.md +552 -0
- package/bin/skills/peer-review/references/paper_mechanics.md +269 -0
- package/bin/skills/peer-review/references/reporting_standards.md +290 -0
- package/bin/skills/peer-review/references/scoring_rubric.md +239 -0
- package/bin/skills/pptx-posters/SKILL.md +410 -0
- package/bin/skills/pptx-posters/assets/poster_html_template.html +257 -0
- package/bin/skills/pptx-posters/assets/poster_quality_checklist.md +358 -0
- package/bin/skills/pptx-posters/references/poster_content_guide.md +748 -0
- package/bin/skills/pptx-posters/references/poster_design_principles.md +806 -0
- package/bin/skills/pptx-posters/references/poster_layout_design.md +900 -0
- package/bin/skills/research-grants/README.md +285 -0
- package/bin/skills/research-grants/SKILL.md +938 -0
- package/bin/skills/research-grants/assets/budget_justification_template.md +453 -0
- package/bin/skills/research-grants/assets/nih_specific_aims_template.md +166 -0
- package/bin/skills/research-grants/assets/nsf_project_summary_template.md +92 -0
- package/bin/skills/research-grants/references/broader_impacts.md +392 -0
- package/bin/skills/research-grants/references/darpa_guidelines.md +636 -0
- package/bin/skills/research-grants/references/doe_guidelines.md +586 -0
- package/bin/skills/research-grants/references/nih_guidelines.md +851 -0
- package/bin/skills/research-grants/references/nsf_guidelines.md +570 -0
- package/bin/skills/research-grants/references/specific_aims_guide.md +458 -0
- package/bin/skills/research-lookup/README.md +156 -0
- package/bin/skills/research-lookup/SKILL.md +606 -0
- package/bin/skills/research-lookup/examples.py +174 -0
- package/bin/skills/research-lookup/lookup.py +187 -0
- package/bin/skills/research-lookup/research_lookup.py +483 -0
- package/bin/skills/research-lookup/scripts/research_lookup.py +483 -0
- package/bin/skills/scholar-evaluation/SKILL.md +289 -0
- package/bin/skills/scholar-evaluation/references/evaluation_framework.md +663 -0
- package/bin/skills/scholar-evaluation/scripts/calculate_scores.py +366 -0
- package/bin/skills/scientific-critical-thinking/SKILL.md +566 -0
- package/bin/skills/scientific-critical-thinking/references/common_biases.md +364 -0
- package/bin/skills/scientific-critical-thinking/references/evidence_hierarchy.md +484 -0
- package/bin/skills/scientific-critical-thinking/references/experimental_design.md +496 -0
- package/bin/skills/scientific-critical-thinking/references/logical_fallacies.md +478 -0
- package/bin/skills/scientific-critical-thinking/references/scientific_method.md +169 -0
- package/bin/skills/scientific-critical-thinking/references/statistical_pitfalls.md +506 -0
- package/bin/skills/scientific-schematics/QUICK_REFERENCE.md +207 -0
- package/bin/skills/scientific-schematics/README.md +327 -0
- package/bin/skills/scientific-schematics/SKILL.md +615 -0
- package/bin/skills/scientific-schematics/example_usage.sh +89 -0
- package/bin/skills/scientific-schematics/references/best_practices.md +559 -0
- package/bin/skills/scientific-schematics/scripts/generate_schematic.py +135 -0
- package/bin/skills/scientific-schematics/scripts/generate_schematic_ai.py +807 -0
- package/bin/skills/scientific-schematics/test_ai_generation.py +243 -0
- package/bin/skills/scientific-slides/SKILL.md +942 -0
- package/bin/skills/scientific-slides/assets/timing_guidelines.md +597 -0
- package/bin/skills/scientific-slides/references/data_visualization_slides.md +708 -0
- package/bin/skills/scientific-slides/references/presentation_structure.md +642 -0
- package/bin/skills/scientific-slides/references/slide_design_principles.md +849 -0
- package/bin/skills/scientific-slides/references/talk_types_guide.md +687 -0
- package/bin/skills/scientific-slides/references/visual_review_workflow.md +775 -0
- package/bin/skills/scientific-slides/scripts/generate_slide_image.py +143 -0
- package/bin/skills/scientific-slides/scripts/generate_slide_image_ai.py +748 -0
- package/bin/skills/scientific-slides/scripts/pdf_to_images.py +201 -0
- package/bin/skills/scientific-slides/scripts/slides_to_pdf.py +220 -0
- package/bin/skills/scientific-slides/scripts/validate_presentation.py +367 -0
- package/bin/skills/scientific-writing/SKILL.md +714 -0
- package/bin/skills/scientific-writing/assets/REPORT_FORMATTING_GUIDE.md +574 -0
- package/bin/skills/scientific-writing/assets/scientific_report.sty +606 -0
- package/bin/skills/scientific-writing/assets/scientific_report_template.tex +449 -0
- package/bin/skills/scientific-writing/references/citation_styles.md +720 -0
- package/bin/skills/scientific-writing/references/figures_tables.md +806 -0
- package/bin/skills/scientific-writing/references/imrad_structure.md +686 -0
- package/bin/skills/scientific-writing/references/professional_report_formatting.md +664 -0
- package/bin/skills/scientific-writing/references/reporting_guidelines.md +748 -0
- package/bin/skills/scientific-writing/references/writing_principles.md +824 -0
- package/bin/skills/tinker/SKILL.md +2 -3
- package/bin/skills/together-ai/SKILL.md +722 -0
- package/bin/skills/treatment-plans/README.md +488 -0
- package/bin/skills/treatment-plans/SKILL.md +1579 -0
- package/bin/skills/treatment-plans/assets/STYLING_QUICK_REFERENCE.md +185 -0
- package/bin/skills/treatment-plans/assets/chronic_disease_management_plan.tex +665 -0
- package/bin/skills/treatment-plans/assets/general_medical_treatment_plan.tex +547 -0
- package/bin/skills/treatment-plans/assets/medical_treatment_plan.sty +222 -0
- package/bin/skills/treatment-plans/assets/mental_health_treatment_plan.tex +774 -0
- package/bin/skills/treatment-plans/assets/one_page_treatment_plan.tex +193 -0
- package/bin/skills/treatment-plans/assets/pain_management_plan.tex +799 -0
- package/bin/skills/treatment-plans/assets/perioperative_care_plan.tex +753 -0
- package/bin/skills/treatment-plans/assets/quality_checklist.md +471 -0
- package/bin/skills/treatment-plans/assets/rehabilitation_treatment_plan.tex +756 -0
- package/bin/skills/treatment-plans/references/goal_setting_frameworks.md +411 -0
- package/bin/skills/treatment-plans/references/intervention_guidelines.md +507 -0
- package/bin/skills/treatment-plans/references/regulatory_compliance.md +476 -0
- package/bin/skills/treatment-plans/references/specialty_specific_guidelines.md +655 -0
- package/bin/skills/treatment-plans/references/treatment_plan_standards.md +485 -0
- package/bin/skills/treatment-plans/scripts/check_completeness.py +322 -0
- package/bin/skills/treatment-plans/scripts/generate_template.py +233 -0
- package/bin/skills/treatment-plans/scripts/timeline_generator.py +385 -0
- package/bin/skills/treatment-plans/scripts/validate_treatment_plan.py +369 -0
- package/bin/skills/unsloth/SKILL.md +565 -47
- package/bin/skills/unsloth/docs/advanced-rl.md +222 -0
- package/bin/skills/unsloth/docs/chat-templates.md +141 -0
- package/bin/skills/unsloth/docs/datasets.md +489 -0
- package/bin/skills/unsloth/docs/docker-extended.md +99 -0
- package/bin/skills/unsloth/docs/dynamic-ggufs-2.0.md +116 -0
- package/bin/skills/unsloth/docs/dynamic-ggufs-aider.md +118 -0
- package/bin/skills/unsloth/docs/faq.md +91 -0
- package/bin/skills/unsloth/docs/fp16-vs-bf16.md +61 -0
- package/bin/skills/unsloth/docs/fp8-rl.md +224 -0
- package/bin/skills/unsloth/docs/glm-4.7-flash.md +997 -0
- package/bin/skills/unsloth/docs/inference-deployment-overview.md +17 -0
- package/bin/skills/unsloth/docs/inference.md +27 -0
- package/bin/skills/unsloth/docs/installation-docker.md +155 -0
- package/bin/skills/unsloth/docs/installation-pip.md +148 -0
- package/bin/skills/unsloth/docs/kernels-packing.md +190 -0
- package/bin/skills/unsloth/docs/kimi-k2.5.md +634 -0
- package/bin/skills/unsloth/docs/lm-studio.md +235 -0
- package/bin/skills/unsloth/docs/lora-hot-swapping.md +75 -0
- package/bin/skills/unsloth/docs/lora-hyperparameters.md +363 -0
- package/bin/skills/unsloth/docs/memory-efficient-rl.md +267 -0
- package/bin/skills/unsloth/docs/model-selection.md +70 -0
- package/bin/skills/unsloth/docs/models.md +532 -0
- package/bin/skills/unsloth/docs/multi-gpu-ddp.md +90 -0
- package/bin/skills/unsloth/docs/notebooks.md +223 -0
- package/bin/skills/unsloth/docs/overview.md +110 -0
- package/bin/skills/unsloth/docs/qwen3-coder-next-extended.md +900 -0
- package/bin/skills/unsloth/docs/qwen3-coder-next.md +900 -0
- package/bin/skills/unsloth/docs/requirements.md +45 -0
- package/bin/skills/unsloth/docs/reward-hacking.md +25 -0
- package/bin/skills/unsloth/docs/saving-to-gguf.md +138 -0
- package/bin/skills/unsloth/docs/saving-to-ollama.md +46 -0
- package/bin/skills/unsloth/docs/sglang-guide.md +278 -0
- package/bin/skills/unsloth/docs/speculative-decoding.md +70 -0
- package/bin/skills/unsloth/docs/tool-calling.md +334 -0
- package/bin/skills/unsloth/docs/troubleshooting-faq.md +204 -0
- package/bin/skills/unsloth/docs/troubleshooting-inference.md +26 -0
- package/bin/skills/unsloth/docs/tts-fine-tuning.md +149 -0
- package/bin/skills/unsloth/docs/tutorial-grpo.md +273 -0
- package/bin/skills/unsloth/docs/tutorial-llama3-ollama.md +356 -0
- package/bin/skills/unsloth/docs/vision-fine-tuning.md +135 -0
- package/bin/skills/unsloth/docs/vision-rl.md +170 -0
- package/bin/skills/unsloth/docs/vllm-engine-arguments.md +43 -0
- package/bin/skills/unsloth/docs/vllm-guide.md +98 -0
- package/bin/skills/venue-templates/SKILL.md +686 -0
- package/bin/skills/venue-templates/assets/examples/cell_summary_example.md +247 -0
- package/bin/skills/venue-templates/assets/examples/medical_structured_abstract.md +313 -0
- package/bin/skills/venue-templates/assets/examples/nature_abstract_examples.md +213 -0
- package/bin/skills/venue-templates/assets/examples/neurips_introduction_example.md +245 -0
- package/bin/skills/venue-templates/assets/grants/nih_specific_aims.tex +235 -0
- package/bin/skills/venue-templates/assets/grants/nsf_proposal_template.tex +375 -0
- package/bin/skills/venue-templates/assets/journals/nature_article.tex +171 -0
- package/bin/skills/venue-templates/assets/journals/neurips_article.tex +283 -0
- package/bin/skills/venue-templates/assets/journals/plos_one.tex +317 -0
- package/bin/skills/venue-templates/assets/posters/beamerposter_academic.tex +311 -0
- package/bin/skills/venue-templates/references/cell_press_style.md +483 -0
- package/bin/skills/venue-templates/references/conferences_formatting.md +564 -0
- package/bin/skills/venue-templates/references/cs_conference_style.md +463 -0
- package/bin/skills/venue-templates/references/grants_requirements.md +787 -0
- package/bin/skills/venue-templates/references/journals_formatting.md +486 -0
- package/bin/skills/venue-templates/references/medical_journal_styles.md +535 -0
- package/bin/skills/venue-templates/references/ml_conference_style.md +556 -0
- package/bin/skills/venue-templates/references/nature_science_style.md +405 -0
- package/bin/skills/venue-templates/references/posters_guidelines.md +628 -0
- package/bin/skills/venue-templates/references/reviewer_expectations.md +417 -0
- package/bin/skills/venue-templates/references/venue_writing_styles.md +321 -0
- package/bin/skills/venue-templates/scripts/customize_template.py +195 -0
- package/bin/skills/venue-templates/scripts/query_template.py +266 -0
- package/bin/skills/venue-templates/scripts/validate_format.py +250 -0
- package/bin/synsc +0 -0
- package/package.json +1 -1
- package/bin/skills/unsloth/references/index.md +0 -7
- package/bin/skills/unsloth/references/llms-full.md +0 -16799
- package/bin/skills/unsloth/references/llms-txt.md +0 -12044
- package/bin/skills/unsloth/references/llms.md +0 -82
|
@@ -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 argparse
|
|
8
|
+
import re
|
|
9
|
+
import sys
|
|
10
|
+
from collections import OrderedDict
|
|
11
|
+
from typing import Dict, List
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BibTeXFormatter:
|
|
15
|
+
"""Format and clean BibTeX entries."""
|
|
16
|
+
|
|
17
|
+
def __init__(self):
|
|
18
|
+
# Standard field order for readability
|
|
19
|
+
self.field_order = [
|
|
20
|
+
'author',
|
|
21
|
+
'editor',
|
|
22
|
+
'title',
|
|
23
|
+
'booktitle',
|
|
24
|
+
'journal',
|
|
25
|
+
'year',
|
|
26
|
+
'month',
|
|
27
|
+
'volume',
|
|
28
|
+
'number',
|
|
29
|
+
'pages',
|
|
30
|
+
'publisher',
|
|
31
|
+
'address',
|
|
32
|
+
'edition',
|
|
33
|
+
'series',
|
|
34
|
+
'school',
|
|
35
|
+
'institution',
|
|
36
|
+
'organization',
|
|
37
|
+
'howpublished',
|
|
38
|
+
'doi',
|
|
39
|
+
'url',
|
|
40
|
+
'isbn',
|
|
41
|
+
'issn',
|
|
42
|
+
'note',
|
|
43
|
+
'abstract',
|
|
44
|
+
'keywords',
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
def parse_bibtex_file(self, filepath: str) -> List[Dict]:
|
|
48
|
+
"""
|
|
49
|
+
Parse BibTeX file and extract entries.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
filepath: Path to BibTeX file
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
List of entry dictionaries
|
|
56
|
+
"""
|
|
57
|
+
try:
|
|
58
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
59
|
+
content = f.read()
|
|
60
|
+
except Exception as e:
|
|
61
|
+
print(f'Error reading file: {e}', file=sys.stderr)
|
|
62
|
+
return []
|
|
63
|
+
|
|
64
|
+
entries = []
|
|
65
|
+
|
|
66
|
+
# Match BibTeX entries
|
|
67
|
+
pattern = r'@(\w+)\s*\{\s*([^,\s]+)\s*,(.*?)\n\}'
|
|
68
|
+
matches = re.finditer(pattern, content, re.DOTALL | re.IGNORECASE)
|
|
69
|
+
|
|
70
|
+
for match in matches:
|
|
71
|
+
entry_type = match.group(1).lower()
|
|
72
|
+
citation_key = match.group(2).strip()
|
|
73
|
+
fields_text = match.group(3)
|
|
74
|
+
|
|
75
|
+
# Parse fields
|
|
76
|
+
fields = OrderedDict()
|
|
77
|
+
field_pattern = r'(\w+)\s*=\s*\{([^}]*)\}|(\w+)\s*=\s*"([^"]*)"'
|
|
78
|
+
field_matches = re.finditer(field_pattern, fields_text)
|
|
79
|
+
|
|
80
|
+
for field_match in field_matches:
|
|
81
|
+
if field_match.group(1):
|
|
82
|
+
field_name = field_match.group(1).lower()
|
|
83
|
+
field_value = field_match.group(2)
|
|
84
|
+
else:
|
|
85
|
+
field_name = field_match.group(3).lower()
|
|
86
|
+
field_value = field_match.group(4)
|
|
87
|
+
|
|
88
|
+
fields[field_name] = field_value.strip()
|
|
89
|
+
|
|
90
|
+
entries.append({'type': entry_type, 'key': citation_key, 'fields': fields})
|
|
91
|
+
|
|
92
|
+
return entries
|
|
93
|
+
|
|
94
|
+
def format_entry(self, entry: Dict) -> str:
|
|
95
|
+
"""
|
|
96
|
+
Format a single BibTeX entry.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
entry: Entry dictionary
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
Formatted BibTeX string
|
|
103
|
+
"""
|
|
104
|
+
lines = [f'@{entry["type"]}{{{entry["key"]},']
|
|
105
|
+
|
|
106
|
+
# Order fields according to standard order
|
|
107
|
+
ordered_fields = OrderedDict()
|
|
108
|
+
|
|
109
|
+
# Add fields in standard order
|
|
110
|
+
for field_name in self.field_order:
|
|
111
|
+
if field_name in entry['fields']:
|
|
112
|
+
ordered_fields[field_name] = entry['fields'][field_name]
|
|
113
|
+
|
|
114
|
+
# Add any remaining fields
|
|
115
|
+
for field_name, field_value in entry['fields'].items():
|
|
116
|
+
if field_name not in ordered_fields:
|
|
117
|
+
ordered_fields[field_name] = field_value
|
|
118
|
+
|
|
119
|
+
# Format each field
|
|
120
|
+
max_field_len = max(len(f) for f in ordered_fields.keys()) if ordered_fields else 0
|
|
121
|
+
|
|
122
|
+
for field_name, field_value in ordered_fields.items():
|
|
123
|
+
# Pad field name for alignment
|
|
124
|
+
padded_field = field_name.ljust(max_field_len)
|
|
125
|
+
lines.append(f' {padded_field} = {{{field_value}}},')
|
|
126
|
+
|
|
127
|
+
# Remove trailing comma from last field
|
|
128
|
+
if lines[-1].endswith(','):
|
|
129
|
+
lines[-1] = lines[-1][:-1]
|
|
130
|
+
|
|
131
|
+
lines.append('}')
|
|
132
|
+
|
|
133
|
+
return '\n'.join(lines)
|
|
134
|
+
|
|
135
|
+
def fix_common_issues(self, entry: Dict) -> Dict:
|
|
136
|
+
"""
|
|
137
|
+
Fix common formatting issues in entry.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
entry: Entry dictionary
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
Fixed entry dictionary
|
|
144
|
+
"""
|
|
145
|
+
fixed = entry.copy()
|
|
146
|
+
fields = fixed['fields'].copy()
|
|
147
|
+
|
|
148
|
+
# Fix page ranges (single hyphen to double hyphen)
|
|
149
|
+
if 'pages' in fields:
|
|
150
|
+
pages = fields['pages']
|
|
151
|
+
# Replace single hyphen with double hyphen if it's a range
|
|
152
|
+
if re.search(r'\d-\d', pages) and '--' not in pages:
|
|
153
|
+
pages = re.sub(r'(\d)-(\d)', r'\1--\2', pages)
|
|
154
|
+
fields['pages'] = pages
|
|
155
|
+
|
|
156
|
+
# Remove "pp." from pages
|
|
157
|
+
if 'pages' in fields:
|
|
158
|
+
pages = fields['pages']
|
|
159
|
+
pages = re.sub(r'^pp\.\s*', '', pages, flags=re.IGNORECASE)
|
|
160
|
+
fields['pages'] = pages
|
|
161
|
+
|
|
162
|
+
# Fix DOI (remove URL prefix if present)
|
|
163
|
+
if 'doi' in fields:
|
|
164
|
+
doi = fields['doi']
|
|
165
|
+
doi = doi.replace('https://doi.org/', '')
|
|
166
|
+
doi = doi.replace('http://doi.org/', '')
|
|
167
|
+
doi = doi.replace('doi:', '')
|
|
168
|
+
fields['doi'] = doi
|
|
169
|
+
|
|
170
|
+
# Fix author separators (semicolon or ampersand to 'and')
|
|
171
|
+
if 'author' in fields:
|
|
172
|
+
author = fields['author']
|
|
173
|
+
author = author.replace(';', ' and')
|
|
174
|
+
author = author.replace(' & ', ' and ')
|
|
175
|
+
# Clean up multiple 'and's
|
|
176
|
+
author = re.sub(r'\s+and\s+and\s+', ' and ', author)
|
|
177
|
+
fields['author'] = author
|
|
178
|
+
|
|
179
|
+
fixed['fields'] = fields
|
|
180
|
+
return fixed
|
|
181
|
+
|
|
182
|
+
def deduplicate_entries(self, entries: List[Dict]) -> List[Dict]:
|
|
183
|
+
"""
|
|
184
|
+
Remove duplicate entries based on DOI or citation key.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
entries: List of entry dictionaries
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
List of unique entries
|
|
191
|
+
"""
|
|
192
|
+
seen_dois = set()
|
|
193
|
+
seen_keys = set()
|
|
194
|
+
unique_entries = []
|
|
195
|
+
|
|
196
|
+
for entry in entries:
|
|
197
|
+
doi = entry['fields'].get('doi', '').strip()
|
|
198
|
+
key = entry['key']
|
|
199
|
+
|
|
200
|
+
# Check DOI first (more reliable)
|
|
201
|
+
if doi:
|
|
202
|
+
if doi in seen_dois:
|
|
203
|
+
print(f'Duplicate DOI found: {doi} (skipping {key})', file=sys.stderr)
|
|
204
|
+
continue
|
|
205
|
+
seen_dois.add(doi)
|
|
206
|
+
|
|
207
|
+
# Check citation key
|
|
208
|
+
if key in seen_keys:
|
|
209
|
+
print(f'Duplicate citation key found: {key} (skipping)', file=sys.stderr)
|
|
210
|
+
continue
|
|
211
|
+
seen_keys.add(key)
|
|
212
|
+
|
|
213
|
+
unique_entries.append(entry)
|
|
214
|
+
|
|
215
|
+
return unique_entries
|
|
216
|
+
|
|
217
|
+
def sort_entries(self, entries: List[Dict], sort_by: str = 'key', descending: bool = False) -> List[Dict]:
|
|
218
|
+
"""
|
|
219
|
+
Sort entries by specified field.
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
entries: List of entry dictionaries
|
|
223
|
+
sort_by: Field to sort by ('key', 'year', 'author', 'title')
|
|
224
|
+
descending: Sort in descending order
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
Sorted list of entries
|
|
228
|
+
"""
|
|
229
|
+
|
|
230
|
+
def get_sort_key(entry: Dict) -> str:
|
|
231
|
+
if sort_by == 'key':
|
|
232
|
+
return entry['key'].lower()
|
|
233
|
+
elif sort_by == 'year':
|
|
234
|
+
year = entry['fields'].get('year', '9999')
|
|
235
|
+
return year
|
|
236
|
+
elif sort_by == 'author':
|
|
237
|
+
author = entry['fields'].get('author', 'ZZZ')
|
|
238
|
+
# Get last name of first author
|
|
239
|
+
if ',' in author:
|
|
240
|
+
return author.split(',')[0].lower()
|
|
241
|
+
else:
|
|
242
|
+
return author.split()[0].lower() if author else 'zzz'
|
|
243
|
+
elif sort_by == 'title':
|
|
244
|
+
return entry['fields'].get('title', '').lower()
|
|
245
|
+
else:
|
|
246
|
+
return entry['key'].lower()
|
|
247
|
+
|
|
248
|
+
return sorted(entries, key=get_sort_key, reverse=descending)
|
|
249
|
+
|
|
250
|
+
def format_file(
|
|
251
|
+
self,
|
|
252
|
+
filepath: str,
|
|
253
|
+
output: str = None,
|
|
254
|
+
deduplicate: bool = False,
|
|
255
|
+
sort_by: str = None,
|
|
256
|
+
descending: bool = False,
|
|
257
|
+
fix_issues: bool = True,
|
|
258
|
+
) -> None:
|
|
259
|
+
"""
|
|
260
|
+
Format entire BibTeX file.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
filepath: Input BibTeX file
|
|
264
|
+
output: Output file (None for in-place)
|
|
265
|
+
deduplicate: Remove duplicates
|
|
266
|
+
sort_by: Field to sort by
|
|
267
|
+
descending: Sort in descending order
|
|
268
|
+
fix_issues: Fix common formatting issues
|
|
269
|
+
"""
|
|
270
|
+
print(f'Parsing {filepath}...', file=sys.stderr)
|
|
271
|
+
entries = self.parse_bibtex_file(filepath)
|
|
272
|
+
|
|
273
|
+
if not entries:
|
|
274
|
+
print('No entries found', file=sys.stderr)
|
|
275
|
+
return
|
|
276
|
+
|
|
277
|
+
print(f'Found {len(entries)} entries', file=sys.stderr)
|
|
278
|
+
|
|
279
|
+
# Fix common issues
|
|
280
|
+
if fix_issues:
|
|
281
|
+
print('Fixing common issues...', file=sys.stderr)
|
|
282
|
+
entries = [self.fix_common_issues(e) for e in entries]
|
|
283
|
+
|
|
284
|
+
# Deduplicate
|
|
285
|
+
if deduplicate:
|
|
286
|
+
print('Removing duplicates...', file=sys.stderr)
|
|
287
|
+
original_count = len(entries)
|
|
288
|
+
entries = self.deduplicate_entries(entries)
|
|
289
|
+
removed = original_count - len(entries)
|
|
290
|
+
if removed > 0:
|
|
291
|
+
print(f'Removed {removed} duplicate(s)', file=sys.stderr)
|
|
292
|
+
|
|
293
|
+
# Sort
|
|
294
|
+
if sort_by:
|
|
295
|
+
print(f'Sorting by {sort_by}...', file=sys.stderr)
|
|
296
|
+
entries = self.sort_entries(entries, sort_by, descending)
|
|
297
|
+
|
|
298
|
+
# Format entries
|
|
299
|
+
print('Formatting entries...', file=sys.stderr)
|
|
300
|
+
formatted_entries = [self.format_entry(e) for e in entries]
|
|
301
|
+
|
|
302
|
+
# Write output
|
|
303
|
+
output_content = '\n\n'.join(formatted_entries) + '\n'
|
|
304
|
+
|
|
305
|
+
output_file = output or filepath
|
|
306
|
+
try:
|
|
307
|
+
with open(output_file, 'w', encoding='utf-8') as f:
|
|
308
|
+
f.write(output_content)
|
|
309
|
+
print(f'Successfully wrote {len(entries)} entries to {output_file}', file=sys.stderr)
|
|
310
|
+
except Exception as e:
|
|
311
|
+
print(f'Error writing file: {e}', file=sys.stderr)
|
|
312
|
+
sys.exit(1)
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def main():
|
|
316
|
+
"""Command-line interface."""
|
|
317
|
+
parser = argparse.ArgumentParser(
|
|
318
|
+
description='Format, clean, sort, and deduplicate BibTeX files',
|
|
319
|
+
epilog='Example: python format_bibtex.py references.bib --deduplicate --sort year',
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
parser.add_argument('file', help='BibTeX file to format')
|
|
323
|
+
|
|
324
|
+
parser.add_argument('-o', '--output', help='Output file (default: overwrite input file)')
|
|
325
|
+
|
|
326
|
+
parser.add_argument('--deduplicate', action='store_true', help='Remove duplicate entries')
|
|
327
|
+
|
|
328
|
+
parser.add_argument('--sort', choices=['key', 'year', 'author', 'title'], help='Sort entries by field')
|
|
329
|
+
|
|
330
|
+
parser.add_argument('--descending', action='store_true', help='Sort in descending order')
|
|
331
|
+
|
|
332
|
+
parser.add_argument('--no-fix', action='store_true', help='Do not fix common issues')
|
|
333
|
+
|
|
334
|
+
args = parser.parse_args()
|
|
335
|
+
|
|
336
|
+
# Format file
|
|
337
|
+
formatter = BibTeXFormatter()
|
|
338
|
+
formatter.format_file(
|
|
339
|
+
args.file,
|
|
340
|
+
output=args.output,
|
|
341
|
+
deduplicate=args.deduplicate,
|
|
342
|
+
sort_by=args.sort,
|
|
343
|
+
descending=args.descending,
|
|
344
|
+
fix_issues=not args.no_fix,
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
if __name__ == '__main__':
|
|
349
|
+
main()
|
|
@@ -0,0 +1,251 @@
|
|
|
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 argparse
|
|
11
|
+
import json
|
|
12
|
+
import random
|
|
13
|
+
import sys
|
|
14
|
+
import time
|
|
15
|
+
from typing import Dict, List, Optional
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
from scholarly import ProxyGenerator, scholarly
|
|
20
|
+
|
|
21
|
+
SCHOLARLY_AVAILABLE = True
|
|
22
|
+
except ImportError:
|
|
23
|
+
SCHOLARLY_AVAILABLE = False
|
|
24
|
+
print('Warning: scholarly library not installed. Install with: pip install scholarly', file=sys.stderr)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class GoogleScholarSearcher:
|
|
28
|
+
"""Search Google Scholar using scholarly library."""
|
|
29
|
+
|
|
30
|
+
def __init__(self, use_proxy: bool = False):
|
|
31
|
+
"""
|
|
32
|
+
Initialize searcher.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
use_proxy: Use free proxy (helps avoid rate limiting)
|
|
36
|
+
"""
|
|
37
|
+
if not SCHOLARLY_AVAILABLE:
|
|
38
|
+
raise ImportError('scholarly library required. Install with: pip install scholarly')
|
|
39
|
+
|
|
40
|
+
# Setup proxy if requested
|
|
41
|
+
if use_proxy:
|
|
42
|
+
try:
|
|
43
|
+
pg = ProxyGenerator()
|
|
44
|
+
pg.FreeProxies()
|
|
45
|
+
scholarly.use_proxy(pg)
|
|
46
|
+
print('Using free proxy', file=sys.stderr)
|
|
47
|
+
except Exception as e:
|
|
48
|
+
print(f'Warning: Could not setup proxy: {e}', file=sys.stderr)
|
|
49
|
+
|
|
50
|
+
def search(
|
|
51
|
+
self,
|
|
52
|
+
query: str,
|
|
53
|
+
max_results: int = 50,
|
|
54
|
+
year_start: Optional[int] = None,
|
|
55
|
+
year_end: Optional[int] = None,
|
|
56
|
+
sort_by: str = 'relevance',
|
|
57
|
+
) -> List[Dict]:
|
|
58
|
+
"""
|
|
59
|
+
Search Google Scholar.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
query: Search query
|
|
63
|
+
max_results: Maximum number of results
|
|
64
|
+
year_start: Start year filter
|
|
65
|
+
year_end: End year filter
|
|
66
|
+
sort_by: Sort order ('relevance' or 'citations')
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
List of result dictionaries
|
|
70
|
+
"""
|
|
71
|
+
if not SCHOLARLY_AVAILABLE:
|
|
72
|
+
print('Error: scholarly library not installed', file=sys.stderr)
|
|
73
|
+
return []
|
|
74
|
+
|
|
75
|
+
print(f'Searching Google Scholar: {query}', file=sys.stderr)
|
|
76
|
+
print(f'Max results: {max_results}', file=sys.stderr)
|
|
77
|
+
|
|
78
|
+
results = []
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
# Perform search
|
|
82
|
+
search_query = scholarly.search_pubs(query)
|
|
83
|
+
|
|
84
|
+
for i, result in enumerate(search_query):
|
|
85
|
+
if i >= max_results:
|
|
86
|
+
break
|
|
87
|
+
|
|
88
|
+
print(f'Retrieved {i + 1}/{max_results}', file=sys.stderr)
|
|
89
|
+
|
|
90
|
+
# Extract metadata
|
|
91
|
+
metadata = {
|
|
92
|
+
'title': result.get('bib', {}).get('title', ''),
|
|
93
|
+
'authors': ', '.join(result.get('bib', {}).get('author', [])),
|
|
94
|
+
'year': result.get('bib', {}).get('pub_year', ''),
|
|
95
|
+
'venue': result.get('bib', {}).get('venue', ''),
|
|
96
|
+
'abstract': result.get('bib', {}).get('abstract', ''),
|
|
97
|
+
'citations': result.get('num_citations', 0),
|
|
98
|
+
'url': result.get('pub_url', ''),
|
|
99
|
+
'eprint_url': result.get('eprint_url', ''),
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
# Filter by year
|
|
103
|
+
if year_start or year_end:
|
|
104
|
+
try:
|
|
105
|
+
pub_year = int(metadata['year']) if metadata['year'] else 0
|
|
106
|
+
if year_start and pub_year < year_start:
|
|
107
|
+
continue
|
|
108
|
+
if year_end and pub_year > year_end:
|
|
109
|
+
continue
|
|
110
|
+
except ValueError:
|
|
111
|
+
pass
|
|
112
|
+
|
|
113
|
+
results.append(metadata)
|
|
114
|
+
|
|
115
|
+
# Rate limiting to avoid blocking
|
|
116
|
+
time.sleep(random.uniform(2, 5))
|
|
117
|
+
|
|
118
|
+
except Exception as e:
|
|
119
|
+
print(f'Error during search: {e}', file=sys.stderr)
|
|
120
|
+
|
|
121
|
+
# Sort if requested
|
|
122
|
+
if sort_by == 'citations' and results:
|
|
123
|
+
results.sort(key=lambda x: x.get('citations', 0), reverse=True)
|
|
124
|
+
|
|
125
|
+
return results
|
|
126
|
+
|
|
127
|
+
def metadata_to_bibtex(self, metadata: Dict) -> str:
|
|
128
|
+
"""Convert metadata to BibTeX format."""
|
|
129
|
+
# Generate citation key
|
|
130
|
+
if metadata.get('authors'):
|
|
131
|
+
first_author = metadata['authors'].split(',')[0].strip()
|
|
132
|
+
last_name = first_author.split()[-1] if first_author else 'Unknown'
|
|
133
|
+
else:
|
|
134
|
+
last_name = 'Unknown'
|
|
135
|
+
|
|
136
|
+
year = metadata.get('year', 'XXXX')
|
|
137
|
+
|
|
138
|
+
# Get keyword from title
|
|
139
|
+
import re
|
|
140
|
+
|
|
141
|
+
title = metadata.get('title', '')
|
|
142
|
+
words = re.findall(r'\b[a-zA-Z]{4,}\b', title)
|
|
143
|
+
keyword = words[0].lower() if words else 'paper'
|
|
144
|
+
|
|
145
|
+
citation_key = f'{last_name}{year}{keyword}'
|
|
146
|
+
|
|
147
|
+
# Determine entry type (guess based on venue)
|
|
148
|
+
venue = metadata.get('venue', '').lower()
|
|
149
|
+
if 'proceedings' in venue or 'conference' in venue:
|
|
150
|
+
entry_type = 'inproceedings'
|
|
151
|
+
venue_field = 'booktitle'
|
|
152
|
+
else:
|
|
153
|
+
entry_type = 'article'
|
|
154
|
+
venue_field = 'journal'
|
|
155
|
+
|
|
156
|
+
# Build BibTeX
|
|
157
|
+
lines = [f'@{entry_type}{{{citation_key},']
|
|
158
|
+
|
|
159
|
+
# Convert authors format
|
|
160
|
+
if metadata.get('authors'):
|
|
161
|
+
authors = metadata['authors'].replace(',', ' and')
|
|
162
|
+
lines.append(f' author = {{{authors}}},')
|
|
163
|
+
|
|
164
|
+
if metadata.get('title'):
|
|
165
|
+
lines.append(f' title = {{{metadata["title"]}}},')
|
|
166
|
+
|
|
167
|
+
if metadata.get('venue'):
|
|
168
|
+
lines.append(f' {venue_field} = {{{metadata["venue"]}}},')
|
|
169
|
+
|
|
170
|
+
if metadata.get('year'):
|
|
171
|
+
lines.append(f' year = {{{metadata["year"]}}},')
|
|
172
|
+
|
|
173
|
+
if metadata.get('url'):
|
|
174
|
+
lines.append(f' url = {{{metadata["url"]}}},')
|
|
175
|
+
|
|
176
|
+
if metadata.get('citations'):
|
|
177
|
+
lines.append(f' note = {{Cited by: {metadata["citations"]}}},')
|
|
178
|
+
|
|
179
|
+
# Remove trailing comma
|
|
180
|
+
if lines[-1].endswith(','):
|
|
181
|
+
lines[-1] = lines[-1][:-1]
|
|
182
|
+
|
|
183
|
+
lines.append('}')
|
|
184
|
+
|
|
185
|
+
return '\n'.join(lines)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def main():
|
|
189
|
+
"""Command-line interface."""
|
|
190
|
+
parser = argparse.ArgumentParser(
|
|
191
|
+
description='Search Google Scholar (requires scholarly library)',
|
|
192
|
+
epilog='Example: python search_google_scholar.py "machine learning" --limit 50',
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
parser.add_argument('query', help='Search query')
|
|
196
|
+
|
|
197
|
+
parser.add_argument('--limit', type=int, default=50, help='Maximum number of results (default: 50)')
|
|
198
|
+
|
|
199
|
+
parser.add_argument('--year-start', type=int, help='Start year for filtering')
|
|
200
|
+
|
|
201
|
+
parser.add_argument('--year-end', type=int, help='End year for filtering')
|
|
202
|
+
|
|
203
|
+
parser.add_argument(
|
|
204
|
+
'--sort-by', choices=['relevance', 'citations'], default='relevance', help='Sort order (default: relevance)'
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
parser.add_argument('--use-proxy', action='store_true', help='Use free proxy to avoid rate limiting')
|
|
208
|
+
|
|
209
|
+
parser.add_argument('-o', '--output', help='Output file (default: stdout)')
|
|
210
|
+
|
|
211
|
+
parser.add_argument('--format', choices=['json', 'bibtex'], default='json', help='Output format (default: json)')
|
|
212
|
+
|
|
213
|
+
args = parser.parse_args()
|
|
214
|
+
|
|
215
|
+
if not SCHOLARLY_AVAILABLE:
|
|
216
|
+
print('\nError: scholarly library not installed', file=sys.stderr)
|
|
217
|
+
print('Install with: pip install scholarly', file=sys.stderr)
|
|
218
|
+
print('\nAlternatively, use PubMed search for biomedical literature:', file=sys.stderr)
|
|
219
|
+
print(' python search_pubmed.py "your query"', file=sys.stderr)
|
|
220
|
+
sys.exit(1)
|
|
221
|
+
|
|
222
|
+
# Search
|
|
223
|
+
searcher = GoogleScholarSearcher(use_proxy=args.use_proxy)
|
|
224
|
+
results = searcher.search(
|
|
225
|
+
args.query, max_results=args.limit, year_start=args.year_start, year_end=args.year_end, sort_by=args.sort_by
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
if not results:
|
|
229
|
+
print('No results found', file=sys.stderr)
|
|
230
|
+
sys.exit(1)
|
|
231
|
+
|
|
232
|
+
# Format output
|
|
233
|
+
if args.format == 'json':
|
|
234
|
+
output = json.dumps({'query': args.query, 'count': len(results), 'results': results}, indent=2)
|
|
235
|
+
else: # bibtex
|
|
236
|
+
bibtex_entries = [searcher.metadata_to_bibtex(r) for r in results]
|
|
237
|
+
output = '\n\n'.join(bibtex_entries) + '\n'
|
|
238
|
+
|
|
239
|
+
# Write output
|
|
240
|
+
if args.output:
|
|
241
|
+
with open(args.output, 'w', encoding='utf-8') as f:
|
|
242
|
+
f.write(output)
|
|
243
|
+
print(f'Wrote {len(results)} results to {args.output}', file=sys.stderr)
|
|
244
|
+
else:
|
|
245
|
+
print(output)
|
|
246
|
+
|
|
247
|
+
print(f'\nRetrieved {len(results)} results', file=sys.stderr)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
if __name__ == '__main__':
|
|
251
|
+
main()
|