uses preprocess instead of filter