code: public Map<String, Object> parse(JBakeConfiguration config, File file) {
          this.configuration = config;
          List<String> fileContents;
          try (InputStream is = new FileInputStream(file)) {
  
              fileContents = IOUtils.readLines(is, config.getRenderEncoding());
          } catch (IOException e) {
              LOGGER.error("Error while opening file {}", file, e);
  
              return null;
          }
  
          boolean hasHeader = hasHeader(fileContents);
          ParserContext context = new ParserContext(
                  file,
                  fileContents,
                  config,
                  hasHeader
          );
  
          if (hasHeader) {
              // read header from file
              processDefaultHeader(context);
          }
          // then read engine specific headers
          processHeader(context);
  
          setModelDefaultsIfNotSetInHeader(context);
          sanitizeTags(context);
  
          if (context.getType().isEmpty() || context.getStatus().isEmpty()) {
              // output error
              LOGGER.warn("Parsing skipped (missing type or status value in header meta data) for file {}!", file);
              return null;
          }
  
          // generate default body
          processDefaultBody(context);
  
          // eventually process body using specific engine
          if (validate(context)) {
              processBody(context);
          } else {
              LOGGER.error("Incomplete source file ({}) for markup engine: {}", file, getClass().getSimpleName());
              return null;
          }
          // TODO: post parsing plugins to hook in here?
  
          return context.getDocumentModel();
      }
docs: Parse given file to extract as much infos as possible
  
  @param file file to process
  @return a map containing all infos. Returning null indicates an error, even if an exception would be better.