Implement basic stdout emitter
This commit is contained in:
parent
ffd5ac52e7
commit
c92d0c9635
@ -16,13 +16,14 @@
|
||||
|
||||
from .emitter import Emitter, known_emitters
|
||||
from .emitter.cgit import CgitEmitter
|
||||
from .emitter.stdout import StdoutEmitter
|
||||
from .parser import Parser
|
||||
|
||||
import argparse
|
||||
|
||||
# Initialise ArgumentParser
|
||||
arg_parser = argparse.ArgumentParser(prog='htmlcc', description='Statically compiled HTML templates for C')
|
||||
arg_parser.add_argument('--emitter', default='cgit', choices=list(known_emitters.keys()))
|
||||
arg_parser.add_argument('--emitter', default='stdout', choices=list(known_emitters.keys()))
|
||||
arg_parser.add_argument('filename', nargs='+')
|
||||
|
||||
args = arg_parser.parse_args()
|
||||
|
86
htmlcc/emitter/stdout.py
Normal file
86
htmlcc/emitter/stdout.py
Normal file
@ -0,0 +1,86 @@
|
||||
# htmlcc - Statically compiled HTML templates for C
|
||||
# Copyright (C) 2025 Lee Yingtong Li
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from . import Emitter, register_emitter
|
||||
|
||||
class StdoutEmitter(Emitter):
|
||||
"""Emitter which prints templates to stdout (useful for testing/demonstration)"""
|
||||
|
||||
def emit_preamble(self) -> None:
|
||||
self.emit(r'''#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void output_variable_encoded(char *variable, bool encode_quotes) {
|
||||
// First compute size of buffer required
|
||||
size_t extra_chars = 0;
|
||||
char *ptr = variable;
|
||||
for (; *ptr != '\0'; ptr++) {
|
||||
if (*ptr == '&') { extra_chars += 4; }
|
||||
if (*ptr == '<') { extra_chars += 3; }
|
||||
if (*ptr == '"' && encode_quotes) { extra_chars += 5; }
|
||||
if (*ptr == '\'' && encode_quotes) { extra_chars += 4; }
|
||||
}
|
||||
|
||||
size_t len = ptr - variable;
|
||||
char *buf = malloc(len + extra_chars + 1);
|
||||
|
||||
// Replace characters
|
||||
char *c_inp = variable;
|
||||
char *c_out = buf;
|
||||
for (; *c_inp != '\0'; c_inp++) {
|
||||
if (*c_inp == '&') {
|
||||
*c_out++ = '&'; *c_out++ = 'a'; *c_out++ = 'm'; *c_out++ = 'p'; *c_out++ = ';';
|
||||
} else if (*c_inp == '<') {
|
||||
*c_out++ = '&'; *c_out++ = 'l'; *c_out++ = 't'; *c_out++ = ';';
|
||||
} else if (*c_inp == '"' && encode_quotes) {
|
||||
*c_out++ = '&'; *c_out++ = 'q'; *c_out++ = 'u'; *c_out++ = 'o'; *c_out++ = 't'; *c_out++ = ';';
|
||||
} else if (*c_inp == '\'' && encode_quotes) {
|
||||
*c_out++ = '&'; *c_out++ = '#'; *c_out++ = '3'; *c_out++ = '9'; *c_out++ = ';';
|
||||
} else {
|
||||
*c_out++ = *c_inp;
|
||||
}
|
||||
}
|
||||
*c_out = '\0';
|
||||
|
||||
printf("%s", buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void output_variable_as_attr(char *variable) {
|
||||
output_variable_encoded(variable, true);
|
||||
}
|
||||
|
||||
void output_variable_as_text(char *variable) {
|
||||
output_variable_encoded(variable, false);
|
||||
}''')
|
||||
|
||||
def output_literal_string(self, literal_string: str) -> None:
|
||||
self.emit(f'printf("%s", {self.escape_cstr(literal_string)});')
|
||||
|
||||
def output_variable_as_attr(self, variable: str) -> None:
|
||||
self.emit(f'output_variable_as_attr({variable});')
|
||||
|
||||
def output_variable_as_text(self, variable: str) -> None:
|
||||
self.emit(f'output_variable_as_text({variable});')
|
||||
|
||||
def output_variable_formatted(self, format_string: str, variable: str) -> None:
|
||||
self.emit(f'printf({self.escape_cstr(format_string)}, {variable});')
|
||||
|
||||
def output_variable_urlencoded(self, variable: str) -> None:
|
||||
raise NotImplementedError('urlencode filter is not implemented for the stdout emitter')
|
||||
|
||||
register_emitter('stdout', StdoutEmitter)
|
Loading…
x
Reference in New Issue
Block a user