Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undo PIMPL pattern in Environment #127

Merged
merged 2 commits into from
Nov 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 37 additions & 47 deletions include/inja/environment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,84 +28,64 @@ using json = nlohmann::json;
* \brief Class for changing the configuration.
*/
class Environment {
class Impl {
public:
std::string input_path;
std::string output_path;

LexerConfig lexer_config;
ParserConfig parser_config;

FunctionStorage callbacks;
TemplateStorage included_templates;
};

std::unique_ptr<Impl> m_impl;

public:
Environment(): Environment("") { }

explicit Environment(const std::string& global_path): m_impl(stdinja::make_unique<Impl>()) {
m_impl->input_path = global_path;
m_impl->output_path = global_path;
}
explicit Environment(const std::string& global_path): m_input_path(global_path), m_output_path(global_path) {}

explicit Environment(const std::string& input_path, const std::string& output_path): m_impl(stdinja::make_unique<Impl>()) {
m_impl->input_path = input_path;
m_impl->output_path = output_path;
}
Environment(const std::string& input_path, const std::string& output_path): m_input_path(input_path), m_output_path(output_path) {}

/// Sets the opener and closer for template statements
void set_statement(const std::string& open, const std::string& close) {
m_impl->lexer_config.statement_open = open;
m_impl->lexer_config.statement_close = close;
m_impl->lexer_config.update_open_chars();
m_lexer_config.statement_open = open;
m_lexer_config.statement_close = close;
m_lexer_config.update_open_chars();
}

/// Sets the opener for template line statements
void set_line_statement(const std::string& open) {
m_impl->lexer_config.line_statement = open;
m_impl->lexer_config.update_open_chars();
m_lexer_config.line_statement = open;
m_lexer_config.update_open_chars();
}

/// Sets the opener and closer for template expressions
void set_expression(const std::string& open, const std::string& close) {
m_impl->lexer_config.expression_open = open;
m_impl->lexer_config.expression_close = close;
m_impl->lexer_config.update_open_chars();
m_lexer_config.expression_open = open;
m_lexer_config.expression_close = close;
m_lexer_config.update_open_chars();
}

/// Sets the opener and closer for template comments
void set_comment(const std::string& open, const std::string& close) {
m_impl->lexer_config.comment_open = open;
m_impl->lexer_config.comment_close = close;
m_impl->lexer_config.update_open_chars();
m_lexer_config.comment_open = open;
m_lexer_config.comment_close = close;
m_lexer_config.update_open_chars();
}

/// Sets whether to remove the first newline after a block
void set_trim_blocks(bool trim_blocks) {
m_impl->lexer_config.trim_blocks = trim_blocks;
m_lexer_config.trim_blocks = trim_blocks;
}

/// Sets whether to strip the spaces and tabs from the start of a line to a block
void set_lstrip_blocks(bool lstrip_blocks) {
m_impl->lexer_config.lstrip_blocks = lstrip_blocks;
m_lexer_config.lstrip_blocks = lstrip_blocks;
}

/// Sets the element notation syntax
void set_element_notation(ElementNotation notation) {
m_impl->parser_config.notation = notation;
m_parser_config.notation = notation;
}


Template parse(nonstd::string_view input) {
Parser parser(m_impl->parser_config, m_impl->lexer_config, m_impl->included_templates);
Parser parser(m_parser_config, m_lexer_config, m_included_templates);
return parser.parse(input);
}

Template parse_template(const std::string& filename) {
Parser parser(m_impl->parser_config, m_impl->lexer_config, m_impl->included_templates);
return parser.parse_template(m_impl->input_path + static_cast<std::string>(filename));
Parser parser(m_parser_config, m_lexer_config, m_included_templates);
return parser.parse_template(m_input_path + static_cast<std::string>(filename));
}

std::string render(nonstd::string_view input, const json& data) {
Expand All @@ -128,13 +108,13 @@ class Environment {
}

void write(const std::string& filename, const json& data, const std::string& filename_out) {
std::ofstream file(m_impl->output_path + filename_out);
std::ofstream file(m_output_path + filename_out);
file << render_file(filename, data);
file.close();
}

void write(const Template& temp, const json& data, const std::string& filename_out) {
std::ofstream file(m_impl->output_path + filename_out);
std::ofstream file(m_output_path + filename_out);
file << render(temp, data);
file.close();
}
Expand All @@ -150,33 +130,43 @@ class Environment {
}

std::ostream& render_to(std::ostream& os, const Template& tmpl, const json& data) {
Renderer(m_impl->included_templates, m_impl->callbacks).render_to(os, tmpl, data);
Renderer(m_included_templates, m_callbacks).render_to(os, tmpl, data);
return os;
}

std::string load_file(const std::string& filename) {
Parser parser(m_impl->parser_config, m_impl->lexer_config, m_impl->included_templates);
return parser.load_file(m_impl->input_path + filename);
Parser parser(m_parser_config, m_lexer_config, m_included_templates);
return parser.load_file(m_input_path + filename);
}

json load_json(const std::string& filename) {
std::ifstream file = open_file_or_throw(m_impl->input_path + filename);
std::ifstream file = open_file_or_throw(m_input_path + filename);
json j;
file >> j;
return j;
}

void add_callback(const std::string& name, unsigned int numArgs, const CallbackFunction& callback) {
m_impl->callbacks.add_callback(name, numArgs, callback);
m_callbacks.add_callback(name, numArgs, callback);
}

/** Includes a template with a given name into the environment.
* Then, a template can be rendered in another template using the
* include "<name>" syntax.
*/
void include_template(const std::string& name, const Template& tmpl) {
m_impl->included_templates[name] = tmpl;
m_included_templates[name] = tmpl;
}

private:
std::string m_input_path;
std::string m_output_path;

LexerConfig m_lexer_config;
ParserConfig m_parser_config;

FunctionStorage m_callbacks;
TemplateStorage m_included_templates;
};

/*!
Expand Down
Loading