documentfolder.jl

Pollen/rewriters/documentfolder.jl is a source file in module Pollen

			
			
			
			
			
			"""
			

			    DocumentFolder(dirs; kwargs...) <: Rewriter

			

			A [`Rewriter`](#) that creates new documents from files in the directories `dirs`.

			

			Also handles watching and reloading files in development mode.

			

			See [`DocumentFiles`](#) and [`SourceFiles`](#) as examples of how it is used.

			

			## Keyword arguments

			

			- `filterfn`: Function `filepath -> Bool` that filters which files are loaded

			- `loadfn`: Function `filepath -> Node` that loads a file into a [`Node`](#)

			"""
			

			
			
			Base
			.
			
			@
			kwdef
			 
			
			
			struct
			
			 

	
			DocumentFolder
			 
			<:
			 

	
			Rewriter
			
			
    
			
			dirs
			::
			
			Vector
			{
			
			Pair
			{
			String
			,
			 
			String
			}
			}
			
    
			
			filterfn
			 
			=
			 
			

	
			hasextension
			(
			
			[
			
			"
			md
			"
			,
			 
			
			"
			ipynb
			"
			]
			)
			
    
			
			loadfn
			 
			=
			 
			_defaultload
			
    
			
			
			files
			::
			
			Dict
			{
			String
			,
			 

	
			FileLoader
			}
			 
			=
			 
			
			
			Dict
			{
			String
			,
			 

	
			FileLoader
			}
			(
			)
			

			end
			

			
			
			_defaultload
			(
			file
			,
			 
			_
			)
			 
			=
			 
			
			
			Pollen
			.
			

	
			parse
			(
			
			Path
			(
			file
			)
			)
			

			

			
			function
			 
			
			
			Base
			.
			
			show
			(
			
			io
			::
			IO
			,
			 
			
			df
			::

	
			DocumentFolder
			)
			
			
    
			
			print
			(
			io
			,
			 
			
			"
			DocumentFolder(
			"
			,
			 
			
			length
			(
			
			keys
			(
			
			df
			.
			
			files
			)
			)
			,
			 
			
			"
			 files, 
			"
			,
			 
			
			length
			(
			
			df
			.
			
			dirs
			)
			,
			
          
			
			"
			 folders)
			"
			)
			

			end
			

			

			
			function
			 
			

	
			DocumentFolder
			(
			
			dirs
			::
			Vector
			
			;
			 
			
			kwargs
			...
			)
			
			
    
			

	
			DocumentFolder
			(
			
			;
			 
			
			dirs
			 
			=
			 
			
			map
			(
			
			d
			 
			->
			
			
			 
			d
			 
			isa
			 
			Pair
			 
			?
			 
			d
			 
			:
			
			 
			
			"
			
			"
			 
			=>
			 
			d
			,
			 
			dirs
			)
			,
			 
			
			kwargs
			...
			)
			

			end
			

			
			

	
			DocumentFolder
			(
			
			dir
			::
			String
			
			;
			 
			
			kwargs
			...
			)
			 
			=
			 
			

	
			DocumentFolder
			(
			
			[
			dir
			]
			
			;
			 
			
			kwargs
			...
			)
			

			

			
			function
			 
			

	
			createsources!
			(
			
			rewriter
			::

	
			DocumentFolder
			)
			
			
    
			
			sources
			 
			=
			 
			
			
			Dict
			{
			String
			,
			 

	
			Node
			}
			(
			)
			
    
			
			for
			
			 
			
			(
			prefix
			,
			 
			dir
			)
			 
			in
			 
			
			rewriter
			.
			
			dirs
			
			
        
			
			for
			
			 
			
			file
			::
			String
			 
			in
			 
			
			filter
			(
			
			rewriter
			.
			
			filterfn
			,
			 
			

	
			rglob
			(
			
			"
			*
			"
			,
			 
			dir
			)
			)
			
			
            
			
			docid
			 
			=
			 
			
			"
			$
			(
			prefix
			)
			$
			(
			
			relpath
			(
			file
			,
			 
			dir
			)
			)
			"
			

			
            
			# Skip if already created
			
            
			
			
			docid
			 
			in
			 
			
			keys
			(
			
			rewriter
			.
			
			files
			)
			 
			&&
			 
			continue
			
            
			
			
			
			rewriter
			.
			
			files
			[
			docid
			]
			 
			=
			 
			

	
			FileLoader
			(
			file
			,
			 
			docid
			,
			
                                               
			
			
			(
			)
			 
			->
			 
			
			
			rewriter
			.
			
			loadfn
			(
			file
			,
			 
			docid
			)
			)
			
            
			
			
			sources
			[
			docid
			]
			 
			=
			 
			
			
			rewriter
			.
			
			loadfn
			(
			file
			,
			 
			docid
			)
			
        
			end
			
    
			end
			
    
			
			return
			 
			sources
			

			end
			

			

			
			function
			 
			

	
			reset!
			(
			
			rewriter
			::

	
			DocumentFolder
			)
			
			
    
			# Clear the dictionary with collected files, so they can be recreated
			
    
			
			empty!
			(
			
			rewriter
			.
			
			files
			)
			

			end
			

			

			
			function
			 
			

	
			geteventhandler
			(
			
			rewriter
			::

	
			DocumentFolder
			,
			 
			ch
			)
			
			
    
			
			return
			 
			

	
			makefilewatcher
			(
			ch
			,
			 
			
			collect
			(
			
			values
			(
			
			rewriter
			.
			
			files
			)
			)
			,
			 
			
			last
			.
			
			(
			
			rewriter
			.
			
			dirs
			)
			)
			

			end
			

			

			
			
			
			"""
			

			    DocumentationFiles(modules; kwargs) <: Rewriter

			

			A [`Rewriter`](#) that finds written documentation like `.md` files in the package

			directories of `modules` and adds them to a [`Project`]'s.

			

			It finds all files in the directories `dir = pkgdir(m ∈ modules)`. Then, if the file's

			extension matches one of `extensions`, a document with ID

			`"(pkgname)"@(pkgversion)/(filepath)` is created.

			

			Also handles watching and reloading files in development mode.

			

			## Keyword arguments

			

			- `extensions = ["md", "ipynb"]`: File extensions to include

			- `pkgtags = Dict()`: Overwrite package versions

			

			"""
			

			
			function
			 
			

	
			DocumentationFiles
			(
			
			ms
			::
			
			Vector
			{
			Module
			}
			
			;
			 
			
			extensions
			 
			=
			 
			
			[
			
			"
			md
			"
			,
			 
			
			"
			ipynb
			"
			]
			,
			
                            
			
			pkgtags
			 
			=
			 
			
			
			Dict
			{
			String
			,
			 
			String
			}
			(
			)
			,
			 
			
			kwargs
			...
			)
			
			
    
			
			filterfn
			 
			=
			 
			

	
			hasextension
			(
			extensions
			)
			
    
			
			pkgdirs
			 
			=
			 
			
			pkgdir
			.
			
			(
			ms
			)
			
    
			
			pkgids
			 
			=
			 
			
			__getpkgids
			(
			ms
			
			;
			 
			pkgtags
			)
			
    
			
			if
			 
			
			any
			(
			isnothing
			,
			 
			pkgdirs
			)
			
			
        
			
			
			i
			::
			Int
			 
			=
			 
			
			findfirst
			(
			isnothing
			,
			 
			pkgdirs
			)
			
        
			
			throw
			(
			
			ArgumentError
			(
			
			"
			Could not find a package directory for module '
			$
			(
			
			ms
			[
			i
			]
			)
			'
			"
			)
			)
			
    
			end
			
    
			
			return
			 
			

	
			DocumentFolder
			(
			
			[
			
			
			
			"
			$
			pkgid
			/doc/
			"
			 
			=>
			 
			dir
			 
			for
			
			 
			
			(
			pkgid
			,
			 
			dir
			)
			 
			in
			 
			
			zip
			(
			pkgids
			,
			 
			pkgdirs
			)
			]
			
			;
			
                          
			filterfn
			,
			 
			
			loadfn
			 
			=
			 
			__load_documentation_file
			,
			 
			
			kwargs
			...
			)
			

			end
			

			
			

	
			DocumentationFiles
			(
			
			m
			::
			Module
			
			;
			 
			
			kwargs
			...
			)
			 
			=
			 
			

	
			DocumentationFiles
			(
			
			[
			m
			]
			
			;
			 
			
			kwargs
			...
			)
			

			

			
			function
			 
			
			__load_documentation_file
			(
			file
			,
			 
			id
			)
			
			
    
			
			pfile
			 
			=
			 
			
			Path
			(
			file
			)
			
    
			
			doc
			 
			=
			 
			
			
			Pollen
			.
			

	
			parse
			(
			pfile
			)
			
    
			
			node_title
			 
			=
			 
			

	
			selectfirst
			(
			doc
			,
			 
			

	
			SelectTag
			(
			
			:
			h1
			)
			)
			
    
			
			title
			 
			=
			
			 
			
			isnothing
			(
			node_title
			)
			 
			?
			 
			
			filename
			(
			pfile
			)
			 
			:
			 
			

	
			gettext
			(
			node_title
			)
			
    
			
			attrs
			 
			=
			 
			
			Dict
			(
			
			
			:
			path
			 
			=>
			 
			
			string
			(
			file
			)
			,
			 
			
			
			:
			title
			 
			=>
			 
			title
			)
			
    
			
			return
			 
			

	
			Node
			(
			
			:
			document
			,
			 
			
			[
			doc
			]
			,
			 
			attrs
			)
			

			end

Utilities


			
			
			
			function
			 
			
			__getpkgids
			(
			ms
			
			;
			 
			
			pkgtags
			 
			=
			 
			
			
			Dict
			{
			String
			,
			 
			String
			}
			(
			)
			)
			
			
    
			
			return
			 
			
			[
			
			
			"
			$
			m
			@
			$
			(
			
			get
			(
			pkgtags
			,
			 
			
			string
			(
			m
			)
			,
			 
			
			
			ModuleInfo
			.
			
			packageversion
			(
			m
			)
			)
			)
			"
			
            
			for
			
			 
			m
			 
			in
			 
			ms
			]
			

			end
			

			

			
			

	
			hasextension
			(
			f
			,
			 
			ext
			)
			 
			=
			 
			
			endswith
			(
			f
			,
			 
			
			string
			(
			ext
			)
			)
			

			
			

	
			hasextension
			(
			f
			,
			 
			
			exts
			::
			Vector
			)
			 
			=
			 
			
			any
			(
			
			map
			(
			
			ext
			 
			->
			 
			

	
			hasextension
			(
			f
			,
			 
			ext
			)
			,
			 
			exts
			)
			)
			

			
			

	
			hasextension
			(
			exts
			)
			 
			=
			 
			
			
			Base
			.
			
			Fix2
			(

	
			hasextension
			,
			 
			exts
			)
			

			

			
			function
			 
			

	
			rglob
			(
			
			filepattern
			 
			=
			 
			
			"
			*
			"
			,
			 
			
			dir
			 
			=
			 
			
			pwd
			(
			)
			,
			 
			
			depth
			 
			=
			 
			5
			)
			
			
    
			
			patterns
			 
			=
			 
			
			[
			
			
			"
			$
			(
			
			repeat
			(
			
			"
			*/
			"
			,
			 
			i
			)
			)
			$
			filepattern
			"
			 
			for
			
			 
			i
			 
			in
			
			 
			0
			:
			depth
			]
			
    
			
			return
			 
			
			vcat
			(
			
			
			[
			
			
			glob
			(
			pattern
			,
			 
			dir
			)
			 
			for
			
			 
			pattern
			 
			in
			 
			
			patterns
			[
			
			1
			:
			depth
			]
			]
			...
			)
			

			end
			

			

			
			@
			testset
			 
			
			"
			DocumentFolder [rewriter]
			"
			 
			
			begin
			
    
			
			dir
			 
			=
			 
			
			mktempdir
			(
			)
			
    
			
			touch
			(
			
			joinpath
			(
			dir
			,
			 
			
			"
			test.md
			"
			)
			)
			
    
			
			r
			 
			=
			 
			

	
			DocumentFolder
			(
			
			[
			
			
			"
			pre/
			"
			 
			=>
			 
			dir
			]
			)
			
    
			
			sources
			 
			=
			 
			

	
			createsources!
			(
			r
			)
			
    
			# Should find the file
			
    
			
			@
			test
			
			 
			
			length
			(
			sources
			)
			 
			==
			 
			1
			
    
			# And assign the correct document ID
			
    
			
			@
			test
			
			 
			
			first
			(
			
			keys
			(
			sources
			)
			)
			 
			==
			 
			
			"
			pre/test.md
			"
			
    
			# Since `createsources!` is stateful, the file should only be returned once
			
    
			
			@
			test
			 
			
			isempty
			(
			

	
			createsources!
			(
			r
			)
			)
			
    
			
			touch
			(
			
			joinpath
			(
			dir
			,
			 
			
			"
			test2.md
			"
			)
			)
			
    
			# But a new file will be found
			
    
			
			@
			test
			
			 
			
			"
			pre/test2.md
			"
			 
			in
			 
			
			keys
			(
			

	
			createsources!
			(
			r
			)
			)
			
    
			# After resetting, both files will be found
			
    
			

	
			reset!
			(
			r
			)
			
    
			
			@
			test
			
			 
			
			length
			(
			

	
			createsources!
			(
			r
			)
			)
			 
			==
			 
			2
			

			end