def test_line(self, number, min_len = None, max_len = None): if self.content is None: return False error = None line = self.get_line(number) if line is None: error = '{}:{} line not found'.format(self.path, number) else: if min_len and len(line) < min_len: error = '{}:{} length must be at least {}, is {}: "{}"' \ .format(self.path, number, min_len, len(line), line) elif max_len and len(line) > max_len: error = '{}:{} length must not exceed {}, is {}: "{}"' \ .format(self.path, number, max_len, len(line), line) if error: if self.mode is FileMode.Optional: Util.warning(error) else: Util.error(error) return False return True
def evaluate_block(self, block): # Get the binding's name name = block.capture_call() if name is None: # This block does not call a binding return self.__evaluate_collection(block.tokens) if not self.bindings.contains(name): # Name is unknown, discard block Util.warning('Use of unknown binding {}:\n{}'.format(name, block)) return None binding = self.bindings.get(name) eval_tokens = TokenCollection() if type(binding) is VariableBinding: eval_binding = self.__evaluate_collection(binding.tokens) eval_tokens.add_collection(eval_binding) elif type(binding) is MacroBinding: args = block.capture_args(binding.num_params == 1) if len(args) != binding.num_params: Util.warning('Macro {} takes {} args, got {}:\n{}' .format(name, binding.num_params, len(args), block)) return None self.bindings.push() # Bind each parameter to the supplied argument for arg, param in zip(args, binding.params): self.bindings.add_variable(param.resolve(), TokenCollection([arg])) eval_binding = self.__evaluate_collection(binding.tokens) eval_tokens.add_collection(eval_binding) self.bindings.pop() elif type(binding) is FunctionBinding: args = block.capture_args(binding.num_params == [1]) if len(args) not in binding.num_params: Util.warning('Function {} takes {} args, got {}:\n{}' .format(name, binding.num_params, len(args), block)) return None if binding.lazy: # Feed block tokens directly to function result = binding.func(self, args) if result: result = self.evaluate_block(result) eval_tokens.add_collection(result) else: # Evaluate and resolve each argument arguments = [self.evaluate_block(a).resolve() for a in args] body = binding.func(self, arguments) eval_tokens.add_collection(self.tokenizer.tokenize(body)) # Trim leading and trailing whitespace eval_tokens.trim() # Run page content through Markdown if binding.protected \ and name == self.settings.Content \ and self.imports.Md: content = eval_tokens.resolve() md = self.imports.Md.markdown(content, output_format = 'html5') md_token = Token(TokenType.Text, md) eval_tokens = TokenCollection([md_token]) return eval_tokens