# ---------------------------------------- # GO EXTENSIONS MAKEFILE # ---------------------------------------- # # this specifies how to build many of the GO extensions. # type "make " on command line. # # For dataflow diagram, see # go/ontology/docs/ # # -- GLOBAL VARIABLES -- GOROOT= ../.. OBO= http://purl.obolibrary.org/obo GOEXT= $(OBO)/go/extensions RO= $(OBO)/ro.owl DCE= http://purl.org/dc/elements/1.1 DATE = `date +%Y-%m-%d` RELEASE = $(OBO)/go/releases/`date +%Y-%m-%d` # ---------------------------------------- # TAXON # ---------------------------------------- #GOTAX= $(GOROOT)/quality_control/annotation_checks/taxon_checks/ # change 2014-01-20 : the edit file in this directory is now primary #TAXGROUP=go-taxon-groupings-header.owl #go-taxon-groupings.owl: $(GOTAX)/taxon_union_terms.obo $(TAXGROUP) # owltools $(TAXGROUP) $< --merge-support-ontologies -o $@ go-taxon-groupings.owl: go-taxon-groupings-edit.owl owltools --use-catalog $< --run-reasoner -r hermit --assert-implied -o $@ .PRECIOUS: go-taxon-groupings.owl go-taxon-groupings-merged.obo: go-taxon-groupings.owl owltools $< --merge-imports-closure -o -f obo $@ # See: https://github.com/geneontology/amigo/issues/247 go-taxon-subsets.owl: go-taxon-subsets.obo owltools $< -o $@ # ---------------------------------------- # CHEBI # ---------------------------------------- CHEBI=$(OBO)/chebi.owl CHEBI_LATEST=../external/chebi-latest.obo # Create a module of CHEBI that is required for our substance-by-role materializations chebi_roles.owl.tmp: substance_by_role.owl owltools --use-catalog $< bio-chebi.owl --add-imports-from-supports --extract-module -s $(OBO)/go/extensions/substance_by_role.owl -c --make-subset-by-properties // --extract-mingraph --set-ontology-id $(OBO)/go/extensions/$@ -o $@.tmp # annoying intermediate step requires as OWLAPI won't let us have two ontologies with the same IRI chebi_roles.owl: chebi_roles.owl.tmp owltools $< --set-ontology-id $(OBO)/go/extensions/$@ -o $@ substance_by_role.obo: substance_by_role.owl owltools $< -o -f obo $@ ### BLEEDING EDGE ### # if you need the bleeding edge version, comment out the target above, call # ./GET_CHEBI.sh to wget latest version, and use the following: #$(CHEBI_LATEST): ../external/chebi.owl # obolib-owl2obo -o $@ $< #$(CHEBI_LATEST): # wget ftp://ftp.ebi.ac.uk/pub/databases/chebi/ontology/chebi.obo -O $@ # MF/CHEBI axioms - development x-chemical-mf.obo: $(GOROOT)/scratch/xps/molecular_function_xp_chebi.obo cat $< > $@.tmp && ./util/fix-chem.pl $@.tmp | obo-map-ids.pl uchebi.obo $@.tmp - > $@ # ---------------------------------------- # MIREOTs/MODULES # ---------------------------------------- IMPORTS_REQUESTS = imports_requests.obo IMPORTS = chebi cl po pato ro ncbitaxon uberon fao oba so IMPORT_FILES = $(patsubst %, %_import.owl, $(IMPORTS)) IMPORT_OBO_FILES = $(patsubst %, %_import.obo, $(IMPORTS)) IMPORT_IRIS = $(patsubst %, $(OBO)/go/extensions/%_import.owl, $(IMPORTS)) IMPORT_SEED = import-seed.owl imports: $(IMPORT_OBO_FILES) clean_imports: test -f uberon_mirror.owl && rm uberon_mirror.owl test -f ncbitaxon_mirror.owl && rm ncbitaxon_mirror.owl # -- # ** PRODUCTION IMPORTS ** # -- # The various imports modules require a seed to determine which subset to bring in. # This seed is formed from the editors file plus additional requests. # For example, if the editors file has an axiom referencing CL:1234567, then this # class will be part of the seed set. # # Note that we need to remove existing imports statements, as these would conflict with # the imports we are rebuilding. import-seed.owl: ../editors/gene_ontology_write.obo $(IMPORTS_REQUESTS) owltools --use-catalog $< --expand-macros --remove-imports-declarations $(IMPORTS_REQUESTS) --merge-support-ontologies -o $@ # -- CHEBI -- # see go/ontology/docs/ for full details # we need to bring in axioms from both bio-chebi (conjugate base axioms) as well as substance-by-role CHEBIRELS = RO:0000057 RO:0002233 RO:0002234 RO:0002313 RO:0002233 RO:0002332 RO:0002340 RO:0002345 BFO:0000051 RO:0000087 GOCHEREL:0000000 GOCHEREL:0000001 GOCHEREL:0000002 GOCHEREL:0000003 GOCHEREL:0000004 chebi_import.owl: $(IMPORT_SEED) owltools --use-catalog $< bio-chebi.owl --add-imports-from-supports --extract-module -s $(OBO)/go/extensions/bio-chebi.owl -c --make-subset-by-properties -n $(CHEBIRELS) // --remove-annotation-assertions -r -l --add-obo-shorthand-to-properties --set-ontology-id $(OBO)/go/extensions/$@ -o $@ # -- CL -- # currently uses CL basic - in future we also want to include axioms from CL to other ontologies cl_import.owl: $(IMPORT_SEED) owltools --use-catalog $< $(OBO)/cl/cl-basic.owl --add-imports-from-supports --extract-module -s $(OBO)/cl/cl-basic.owl -c --extract-mingraph --make-subset-by-properties BFO:0000050 RO:0002202 --set-ontology-id $(OBO)/go/extensions/$@ --add-ontology-annotation $(DCE)/title "Cell Ontology Module for GO" -o $@ so_import.owl: $(IMPORT_SEED) owltools --use-catalog $< $(OBO)/so.owl --add-imports-from-supports --extract-module -s $(OBO)/so.owl -c --extract-mingraph --make-subset-by-properties -f --set-ontology-id $(OBO)/go/extensions/$@ --add-ontology-annotation $(DCE)/title "Sequence Ontology Module for GO" -o $@ fao_import.owl: $(IMPORT_SEED) owltools --use-catalog $< $(OBO)/fao.owl --add-imports-from-supports --extract-module -s $(OBO)/fao.owl -c --extract-mingraph --set-ontology-id $(OBO)/go/extensions/$@ -o $@ # TODO - bring in CL to Uberon axioms uberon_mirror.owl: ../editors/gene_ontology_write.obo wget $(OBO)/uberon/ext.owl -O $@ && touch uberon_mirror.owl .PRECIOUS: uberon_mirror.owl ## ---------------------------------------- ## Filtered version of uberon ## ---------------------------------------- # # This is created prior to making the uberon_import module. # # We filter for different reasons: # 1. at avoid bringing in stale copies of parts of GO from uberon imports. See: https://github.com/ontodev/robot/issues/38 # 2. to (optionally) avoid bringing in the very strict taxon constraints from Uberon. See: https://github.com/geneontology/go-ontology/issues/12223 # # The UBERON_FILTER variable has a list of modules that uberon imports that we want to exclude; we do this by removing the import declaration # # Note that the inter-ontology axioms will still be within uberon_filtered, but they will later be excluded as they are dangling # Use this to allow in uberon taxon constraints: UBERON_FILTER = chebi_import envo_import go_import nbo_import pato_import pr_import # Use this to filter out uberon taxon constraints: ##UBERON_FILTER = chebi_import envo_import go_import nbo_import pato_import pr_import ncbitaxon_import UBERON_FILTER_C = $(patsubst %, --remove-import-declaration http://purl.obolibrary.org/obo/uberon/%.owl,$(UBERON_FILTER)) uberon_filtered.owl: uberon_mirror.owl owltools --use-catalog $< $(UBERON_FILTER_C) --merge-imports-closure --remove-classes-in-idspace -s GO --remove-classes-in-idspace -s CHEBI --add-obo-shorthand-to-properties --set-ontology-id $(OBO)/uberon.owl -o $@ .PRECIOUS: uberon_filtered.owl ## -- UBERON -- ## ## OWL module is complete w.r.t. inter-ontology axioms and synonyms+definitions uberon_import.owl: $(IMPORT_SEED) uberon_filtered.owl owltools --use-catalog $< ../editors/uberon-ecas-to-add.obo --merge-support-ontologies uberon_filtered.owl --add-imports-from-supports --extract-module -s $(OBO)/uberon.owl -c --remove-axiom-annotations --make-subset-by-properties -f BFO:0000050 RO:0002202 immediate_transformation_of RO:0002160 RO:0002161 RO:0002162 --remove-annotation-assertions -r -l -s -d --set-ontology-id $(OBO)/go/extensions/$@ --add-ontology-annotation $(DCE)/title "Uberon Ontology Module for GO" -o $@ ## OBO module is much more minimal than the OWL one to avoid OE issues. ## - no links to other ontologies; UBERON ID space only ## - no defs or synonyms; avoids OE issues with unicode #uberon_import.obo: $(IMPORT_SEED) uberon_import.owl # owltools --use-catalog $< $(OBO)/uberon/basic.owl --add-imports-from-supports --extract-module -s $(OBO)/uberon/basic.owl -c --extract-mingraph --set-ontology-id $(OBO)/go/extensions/$@ -o -f obo $@.tmp && grep -v ^owl-axioms $@.tmp > $@ uberon_import.obo: uberon_import.owl owltools $< --remove-external-classes UBERON --extract-mingraph --set-ontology-id $(OBO)/go/extensions/uberon_import.obo -o -f obo --no-check $@.tmp && grep -v ^owl-axioms $@.tmp > $@ # -- PO -- po.owl: $(IMPORT_SEED) wget --no-check-certificate -N $(OBO)/po.owl po_import.owl: $(IMPORT_SEED) po.owl owltools --use-catalog $< po.owl $(OBO)/ro.owl --add-imports-from-supports --extract-module -s $(OBO)/po.owl -c --extract-mingraph --make-subset-by-properties -f BFO:0000050 --set-ontology-id $(OBO)/go/extensions/$@ --add-ontology-annotation $(DCE)/title "Plant Ontology Ontology Module for GO" -o $@ # -- PATO -- pato_import.owl: $(IMPORT_SEED) owltools --use-catalog $< $(OBO)/pato.owl --add-imports-from-supports --extract-module -s $(OBO)/pato.owl -c --extract-mingraph --make-subset-by-properties // --set-ontology-id $(OBO)/go/extensions/$@ --add-ontology-annotation $(DCE)/title "PATO Biological Qualities Ontology Module for GO" -o $@ # -- NCBITaxon -- ncbitaxon.obo: $(IMPORT_SEED) wget --no-check-certificate -N $(OBO)/ncbitaxon.obo && touch $@ ncbitaxon_mirror.owl: ncbitaxon.obo go-taxon-groupings.owl owltools --use-catalog $< $(OBO)/go/extensions/go-taxon-groupings.owl $(OBO)/ncbitaxon/subsets/taxslim-disjoint-over-in-taxon.owl --merge-support-ontologies --remove-imports-declarations --set-ontology-id $(OBO)/ncbitaxon.owl -o $@ && touch $@ ncbitaxon_import.owl: $(IMPORT_SEED) ncbitaxon_mirror.owl owltools --use-catalog $< ncbitaxon_mirror.owl --add-imports-from-supports --extract-module -s $(OBO)/ncbitaxon.owl -c --remove-axiom-annotations --set-ontology-id $(OBO)/go/extensions/$@ --add-ontology-annotation $(DCE)/title "NCBITaxonomy plus Extensions Module for GO" -o $@ pr.obo: $(IMPORT_SEED) wget --no-check-certificate -N $(OBO)/pr.obo pr_mirror.owl: pr.obo owltools $< --make-subset-by-properties // --reasoner-query -r elk PR_000000001 --reasoner-dispose --make-ontology-from-results --extract-mingraph --set-ontology-id $(OBO)/pr.owl -o $@ pr_import.owl: $(IMPORT_SEED) pr_mirror.owl owltools --use-catalog $< $(OBO)/po.owl --add-imports-from-supports --extract-module -s $(OBO)/pr.owl -c --extract-mingraph --set-ontology-id $(OBO)/go/extensions/$@ -o $@ # OBA oba_import.owl: $(IMPORT_SEED) mirror_oba.owl owltools --use-catalog $^ --add-imports-from-supports --extract-module -s $(OBO)/oba.owl -c --extract-mingraph --make-subset-by-properties -f // --remove-dangling --set-ontology-id $(OBO)/go/extensions/$@ -o $@ oba-basic.obo: $(IMPORT_SEED) wget --no-check-certificate $(OBO)/oba/subsets/oba-basic.obo -O $@ && touch $@ mirror_oba.owl: oba-basic.obo owltools $< --remove-imports-declarations --extract-mingraph --set-ontology-id $(OBO)/oba.owl -o $@ # -- RO -- ro_import_ObjectProperties.owl: allrelations.owl seed-for-relations.obo # owltools --use-catalog $< --remove-axioms -t ObjectPropertyDomain --remove-axioms -t ObjectPropertyRange --remove-annotation-assertions -l -d -r -p $(OBO)/IAO_0000425 seed-for-relations.obo --extract-properties --set-ontology-id $(OBO)/go/extensions/$@ --add-ontology-annotation $(DCE)/title "Relations Ontology Module for GO" -o $@ owltools --use-catalog seed-for-relations.obo $< --extract-module -s $(OBO)/ro.owl -c --add-obo-shorthand-to-properties --remove-tbox --remove-axioms -t ObjectPropertyDomain --remove-axioms -t ObjectPropertyRange --remove-annotation-assertions -l -d -r -p $(OBO)/IAO_0000425 --set-ontology-id $(OBO)/go/extensions/ro_import.owl --add-ontology-annotation $(DCE)/title "Relations Ontology Module for GO" -o $@ ro_import.owl: ro_import_ObjectProperties.owl owltools $< never_in_taxon.obo --merge-support-ontologies -o $@ allrelations.owl: seed-for-relations.obo owltools --use-catalog $(OBO)/ro.owl --merge-imports-closure ../editors/gene_ontology_write.obo --merge-imports-closure --set-ontology-id $(OBO)/ro.owl -o $@ seed-for-relations.obo: ../editors/gene_ontology_write.obo owltools $< --remove-imports-declarations --merge-support-ontologies -o -f obo --no-check $@ ro_pending.owl: ro_pending.obo owltools $< -o $@ # -- OWL2OBO for imports -- # # obo translation of owl imports - required for oboedit.catalog in editors directory # we remove untranslateable axioms from the header. # 2014-04-03 - turn of definition imports, causing problems with RO %_import.obo: %_import.owl owltools $< --add-obo-shorthand-to-properties --add-ontology-annotation http://www.geneontology.org/formats/oboInOwl#default-namespace external -o -f obo --no-check $@.tmp && egrep -v '^(owl-axioms|property_value):' $@.tmp | grep -v ^def: > $@ # -- # ** DEV IMPORTS ** # -- #go_fao_subset.owl: x-fungal-anatomy.owl # owltools --use-catalog $< $(OBO)/go.owl --add-imports-from-supports --extract-module -s $(OBO)/go.owl -c --extract-mingraph --set-ontology-id $(OBO)/go/extensions/$@ -o $@ # ---------------------------------------- # DISJOINTS # ---------------------------------------- #x-disjoint.obo: # ---------------------------------------- # GO PLUS and GO PLUS DEV # ---------------------------------------- # post-megafile: make this the live go-plus.owl job # for testing, use go_write_test instead of validated go-plus.owl: ../editors/validated.obo imports bridges owltools --use-catalog $< --set-ontology-id -v $(RELEASE)/extensions/$@ $(OBO)/go/extensions/$@ --add-ontology-annotation $(DCE)/title "Gene Ontology plus external axioms" -o $@ go-plus.obo: go-plus.owl owltools --use-catalog $< --merge-import-closure --remove-dangling -o -f obo --no-check $@.tmp && grep -v ^owl-axioms $@.tmp > $@ go-plus.json: go-plus.owl owltools --use-catalog $< -o -f json $@.tmp && mv $@.tmp $@ #go-plus-dev.obo: go-plus-dev.owl # owltools $< --merge-import-closure -o -f obo $@ # extract equivalent classes axioms %-EquivalentClasses.obo: %.owl go-plus.owl owltools --use-catalog $< --merge-imports-closure --extract-axioms -t EquivalentClasses -o -f obo $@.tmp && grep -v ^owl-axiom $@.tmp > $@ %-mingraph.obo: %.owl go-plus.owl owltools --use-catalog $< --merge-imports-closure --extract-mingraph --idspace GO -o -f obo --no-check $@.tmp && grep -v ^owl-axiom $@.tmp > $@ # ---------------------------------------- # TAXON SUBSETS # ---------------------------------------- # Conventions: always use formal scientific name # species: capitalized genus initial followed by lowercase species; higher taxa: taxon name with capitalized first letter Archaea=2157 Bacteria=2 Drerio=7955 Dmelanogaster=7227 Celegans=6239 Hsapiens=9606 Mammalia=40674 Viridiplantae=33090 TAXIDS=$(Archaea) $(Bacteria) $(Drerio) $(Hsapiens) $(Dmelanogaster) $(Celegans) $(Viridiplantae) tax_subsets: $(patsubst %,../subsets/go-tax-%.obo,$(TAXIDS)) ##../subsets/go-tax-%.obo: go-plus.owl ../subsets/go-tax-%.obo: owltools --use-catalog go-plus.owl $(OBO)/ncbitaxon/subsets/taxslim.owl --add-imports-from-supports --reasoner elk --make-species-subset -t NCBITaxon:$* --remove-dangling --remove-imports-declarations -o -f obo $@.tmp && mv $@.tmp $@ # ---------------------------------------- # DEV XP FILE CONVERSION # ---------------------------------------- x-%.obo: x-%.owl obolib-owl2obo -o $@ $< %-readonly.obo: %.owl owltools --use-catalog $< $*-importer.owl -o -f obo $@ #%-composite.owl: %-importer.owl # owltools $< --add-support-from-imports --merge-support-ontologies -o $@ # owltools --create-ontology $*-composite $< --merge-support-ontologies --add-support-from-imports --merge-support-ontologies -o $@ #%-merged.owl: %.owl # owltools $< --merge-import-closure -o $@ # NOW: x-complex.obo #x-cc-internal.owl: $(GOROOT)/scratch/xps/cellular_component_xp_go.obo # obolib-obo2owl --allow-dangling -o $@ $< # INCORPORATED #x-bp-cc.owl: $(GOROOT)/scratch/xps/biological_process_xp_cellular_component.obo # obolib-obo2owl --allow-dangling -o $@ $< # ---------------------------------------- # DEV LOGICAL DEFINITIONS # ---------------------------------------- # source for these is obo x-mf-protein.owl: x-mf-protein.obo obolib-obo2owl --allow-dangling -o $@ $< x-bp-protein.owl: x-bp-protein.obo obolib-obo2owl --allow-dangling -o $@ $< # @Deprecated XALL= x-core.obo x-cell.obo x-metazoan-anatomy.obo x-planat-anatomy-readonly.obo x-all.obo: $(XALL) obo-cat.pl $(XALL) > $@ # ---------------------------------------- # ANNOTATION RELATIONS # ---------------------------------------- # Create a module from RO that is seeded from the gorel-edit ontology. # Note that to be a seed, a relation needs at least one logical axiom; # we recommend making each RO relation to be seeded a subproperty of 'go annotation extension relation' gorel-ro-import.owl: gorel-edit.owl ro_import.owl owltools $< --add-support-from-imports --extract-module -c -s $(OBO)/ro.owl -o $@ # Public edition: gorel-edit axioms merged with RO module gorel.owl: gorel-edit.owl gorel-ro-import.owl owltools --map-ontology-iri $(OBO)/ro.owl gorel-ro-import.owl $< --merge-imports-closure --add-obo-shorthand-to-properties -o $@ # OBO translation, with symbols as IDs gorel.obo: gorel.owl owltools $< --add-obo-shorthand-to-properties --remove-tbox -o -f obo --no-check $@.tmp && grep -v ^owl-axioms $@.tmp > $@ gorel-examples.owl: $(GOROOT)/scratch/xps/go_annotation_extension_examples.obo gorel.owl owltools $< gorel.owl --merge-support-ontologies -o $@ # ---------------------------------------- # LEGO ANNOTATION RELATIONS # ---------------------------------------- # Create a module from RO that is seeded from the legorel-edit ontology. # Note that to be a seed, a relation needs at least one logical axiom; # we recommend making each RO relation to be seeded a subproperty of 'go annotation extension relation' legorel-ro-import.owl: legorel-edit.owl ro_import.owl owltools $< --add-support-from-imports --extract-module -c -s $(OBO)/ro.owl -o $@ # Public edition: legorel-edit axioms merged with RO module legorel.owl: legorel-edit.owl legorel-ro-import.owl owltools --map-ontology-iri $(OBO)/ro.owl legorel-ro-import.owl $< --merge-imports-closure -o $@ # OBO translation, with symbols as IDs legorel.obo: legorel.owl owltools $< --add-obo-shorthand-to-properties --remove-tbox -o -f obo --no-check $@.tmp && grep -v ^owl-axioms $@.tmp > $@ # ---------------------------------------- # NIFSTD # ---------------------------------------- bridges: go-nifstd-bridge.owl go-nifstd-bridge.obo: ../editors/validated.obo xrefs-to-sao-axioms.pl $< > $@.tmp && mv $@.tmp $@ go-nifstd-bridge.owl: go-nifstd-bridge.obo owltools $< --remove-annotation-assertions -o $@ # ---------------------------------------- # SIO # ---------------------------------------- sio-ro-bridge.obo: sio-ro-bridge-edit.obo cp $< $@ sio-ro-bridge.owl: sio-ro-bridge-edit.obo owltools $< -o -f owl $@ && perl -pi -ne 's@http://purl.obolibrary.org/obo/SIO@http://semanticscience.org/resource/SIO@g' $@ # ---------------------------------------- # REASONER DIFFS - experimental/deprecated # ---------------------------------------- #x-bp-cc.rdiff: # reasoner-diff --reasoner elk ../editors/gene_ontology_write.obo --change ~/cvs/go/scratch/xps/biological_process_xp_cellular_component.obo --report x-metazoan-anatomy.rdiff: x-metazoan-anatomy.owl reasoner-diff --reasoner elk ../editors/gene_ontology_write.obo ../external/obo-relations/ro.owl ../external/uberon/composite-metazoan.owl ../external/cell-ontology/cl.owl --change $< --change x-cell.owl --report $@ # ---------------------------------------- # BIO-ATTRIBUTES # ---------------------------------------- # See: http://wiki.geneontology.org/index.php/Extensions/x-attribute # This may later move to its own repo # # remember to cd vt && make vt-plus.obo bio-attributes-plus-vt.obo: bio-attributes.obo vt/vt-plus.obo obo-subtract.pl $< vt/vt-plus.obo > $@.tmp && obo-simple-merge.pl vt/vt-plus.obo $@.tmp | grep -v ^subset > $@.tmp2 && mv $@.tmp2 $@ # after: cp to bio-attributes.obo # Add TO (plant trait) # remember to cd trair && make trait.obo bio-attributes-plus-to.obo: bio-attributes.obo obo-subtract.pl $< traits/trait.obo > $@.tmp && obo-simple-merge.pl traits/trait.obo $@.tmp > $@.tmp2 && obo-merge-tags.pl -t intersection_of $@.tmp2 traits/trait_xp.obo | grep -v ^subset > $@ # after: cp to bio-attributes.obo #x-attribute.owl: x-attribute.obo # owltools --use-catalog $< bio-attributes.owl --merge-support-ontologies -o $@ # ---------------------------------------- # LEGO # ---------------------------------------- #sync-lego: # cp ../../experimental/lego/owl/lego-relations.owl . lego-relations-import.owl: lego-relations-edit.owl owltools --use-catalog $< --extract-module -c -s $(OBO)/ro.owl -o $@ # ---------------------------------------- # DOCUMENTATION # ---------------------------------------- all_html: $(patsubst %, %_import/.index.html, $(IMPORTS)) # experimental: owltools will generate graphs of import closures, as well as basic metadata as markdown files %.md: %.dot echo done .PRECIOUS: %.md %.dot: %.owl owltools --use-catalog $< --write-imports-dot $@ --ontology-metadata-to-markdown $*.md .PRECIOUS: %.dot %.png: %.dot dot -Grankdir=LR -Tpng $< -o $@ .PRECIOUS: %.png %.cmapx: %.dot %.png dot -Grankdir=LR -Tcmapx $< -o $@ .PRECIOUS: %.cmapx # adds image map %-x.md: %.md %.cmapx %.png ./util/add-map.pl $*.png $< $*.cmapx > $@ .PRECIOUS: %-x.md %-dir: test -d $* || mkdir $* # requires pandoc %/index.html: %-x.md %-dir pandoc $< -o $@ && cp $*.png $*/