You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			74 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			74 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
import os
 | 
						|
from typing import TYPE_CHECKING, Any, Dict, List, Match, Union
 | 
						|
 | 
						|
from ._base import BaseDirective, DirectivePlugin
 | 
						|
 | 
						|
if TYPE_CHECKING:
 | 
						|
    from ..block_parser import BlockParser
 | 
						|
    from ..core import BaseRenderer, BlockState
 | 
						|
    from ..markdown import Markdown
 | 
						|
 | 
						|
 | 
						|
class Include(DirectivePlugin):
 | 
						|
    def parse(
 | 
						|
        self, block: "BlockParser", m: Match[str], state: "BlockState"
 | 
						|
    ) -> Union[Dict[str, Any], List[Dict[str, Any]]]:
 | 
						|
        source_file = state.env.get("__file__")
 | 
						|
        if not source_file:
 | 
						|
            return {"type": "block_error", "raw": "Missing source file"}
 | 
						|
 | 
						|
        encoding = "utf-8"
 | 
						|
        options = self.parse_options(m)
 | 
						|
        if options:
 | 
						|
            attrs = dict(options)
 | 
						|
            if "encoding" in attrs:
 | 
						|
                encoding = attrs["encoding"]
 | 
						|
        else:
 | 
						|
            attrs = {}
 | 
						|
 | 
						|
        relpath = self.parse_title(m)
 | 
						|
        dest = os.path.join(os.path.dirname(source_file), relpath)
 | 
						|
        dest = os.path.normpath(dest)
 | 
						|
 | 
						|
        if dest == source_file:
 | 
						|
            return {
 | 
						|
                "type": "block_error",
 | 
						|
                "raw": "Could not include self: " + relpath,
 | 
						|
            }
 | 
						|
 | 
						|
        if not os.path.isfile(dest):
 | 
						|
            return {
 | 
						|
                "type": "block_error",
 | 
						|
                "raw": "Could not find file: " + relpath,
 | 
						|
            }
 | 
						|
 | 
						|
        with open(dest, "rb") as f:
 | 
						|
            content = f.read().decode(encoding)
 | 
						|
 | 
						|
        ext = os.path.splitext(relpath)[1]
 | 
						|
        if ext in {".md", ".markdown", ".mkd"}:
 | 
						|
            new_state = block.state_cls()
 | 
						|
            new_state.env["__file__"] = dest
 | 
						|
            new_state.process(content)
 | 
						|
            block.parse(new_state)
 | 
						|
            return new_state.tokens
 | 
						|
 | 
						|
        elif ext in {".html", ".xhtml", ".htm"}:
 | 
						|
            return {"type": "block_html", "raw": content}
 | 
						|
 | 
						|
        attrs["filepath"] = dest
 | 
						|
        return {
 | 
						|
            "type": "include",
 | 
						|
            "raw": content,
 | 
						|
            "attrs": attrs,
 | 
						|
        }
 | 
						|
 | 
						|
    def __call__(self, directive: BaseDirective, md: "Markdown") -> None:
 | 
						|
        directive.register("include", self.parse)
 | 
						|
        if md.renderer and md.renderer.NAME == "html":
 | 
						|
            md.renderer.register("include", render_html_include)
 | 
						|
 | 
						|
 | 
						|
def render_html_include(renderer: "BaseRenderer", text: str, **attrs: Any) -> str:
 | 
						|
    return '<pre class="directive-include">\n' + text + "</pre>\n"
 |