def simplify(self, changes): retval = super(HtmlList, self).simplify(changes) if retval is not self: return retval def is_html_text_call(item): return ( isinstance(item, codegen.FunctionCall) and isinstance(item.expr, codegen.VariableReference) and ( "{0}.{1}".format(item.expr.module_name, item.expr.name) == "Html.text" ) ) new_items = [] for item in self.items: if ( len(new_items) > 0 and is_html_text_call(new_items[-1]) and is_html_text_call(item) ): last_item = new_items[-1] if not isinstance(last_item.args[0], codegen.StringConcat): last_item.args = [codegen.StringConcat([last_item.args[0]])] last_item.args[0].parts.append(item.args[0]) changes.append(True) else: new_items.append(item) self.items = new_items return self
def test_string_join_omit_empty_2(self): scope = codegen.Scope() scope.reserve_name("tmp", type=dtypes.String) var = scope.variables["tmp"] join = codegen.StringConcat([codegen.String(""), var]) join = codegen.simplify(join) self.assertCodeEqual( join.as_source_code(), """ tmp """, )
def test_string_join_two(self): scope = codegen.Scope() scope.reserve_name("tmp", type=dtypes.String) var = scope.variables["tmp"] join = codegen.StringConcat([codegen.String("hello "), var]) self.assertCodeEqual( join.as_source_code(), """ String.concat [ "hello " , tmp ] """, )
def test_string_join_collapse_strings(self): scope = codegen.Scope() scope.reserve_name("tmp", type=dtypes.String) var = scope.variables["tmp"] join1 = codegen.StringConcat([ codegen.String("hello "), codegen.String("there "), var, codegen.String(" how"), codegen.String(" are you?"), ]) join1 = codegen.simplify(join1) self.assertCodeEqual( join1.as_source_code(), """ String.concat [ "hello there " , tmp , " how are you?" ] """, )
def dom_nodes_to_elm(nodes, expr_replacements, local_scope, compiler_env): # We have to structure this as a list of lists, then do a List.concat # at the end. In many cases the List.concat will disappear after # simplify. from elm_fluent import compiler items = [] for node in nodes: if isinstance(node, bs4.element.NavigableString): parts = interpolate_replacements(text_type(node), expr_replacements) for part in parts: if isinstance(part, string_types): items.append( HtmlList( [ local_scope.variables["Html.text"].apply( codegen.String(text_type(part)) ) ] ) ) else: val = compiler.compile_expr(part, local_scope, compiler_env) if val.type == html_output_type: # This is a list type, so simply append to our list of lists items.append(val) else: val = local_scope.variables["Html.text"].apply( compiler.Stringable(val, local_scope) ) items.append(HtmlList([val])) else: assert isinstance(node, bs4.element.Tag) tag_name = node.name.lower() static_attributes = [] for attr_name, attr_value in sorted(node.attrs.items()): if isinstance(attr_value, list): # Bs4 treats class attribute differently, returns a list, which we convert # back to a string here: attr_value = " ".join(attr_value) attr_value_parts = interpolate_replacements( attr_value, expr_replacements ) attr_output_parts = [] for part in attr_value_parts: if isinstance(part, string_types): attr_output_parts.append(codegen.String(text_type(part))) else: with compiler_env.modified(html_context=False): attr_output_parts.append( compiler.Stringable( compiler.compile_expr( part, local_scope, compiler_env ), local_scope, from_ftl_source=compiler.make_ftl_source( part, compiler_env ), ) ) attr_final_value = codegen.StringConcat(attr_output_parts) if attr_name in html_attributes.ATTRIBUTES: attr_constructor = local_scope.variables[ "Attributes.{0}".format(attr_name) ] else: attr_constructor = local_scope.variables[ "Attributes.attribute" ].apply(codegen.String(attr_name)) static_attributes.append(attr_constructor.apply(attr_final_value)) if compiler_env.dynamic_html_attributes: selectors_for_node = codegen.List( list( map( codegen.String, get_selectors_for_node(node, expr_replacements), ) ) ) dynamic_attributes = local_scope.variables[ "Fluent.selectAttributes" ].apply( local_scope.variables[compiler.ATTRS_ARG_NAME], selectors_for_node ) else: dynamic_attributes = codegen.List([]) attributes = codegen.ListConcat( [codegen.List(static_attributes), dynamic_attributes], dtypes.List.specialize(a=html.Attribute), ) sub_items = dom_nodes_to_elm( list(node.children), expr_replacements, local_scope, compiler_env ) if tag_name in html.ELEMENTS: node_constructor = local_scope.variables["Html.{0}".format(tag_name)] else: node_constructor = local_scope.variables["Html.node"].apply( codegen.String(tag_name) ) item = node_constructor.apply(attributes, sub_items) items.append(HtmlList([item])) return HtmlListConcat(items)
def test_string_join_one(self): join = codegen.StringConcat([codegen.String("hello")]) join = codegen.simplify(join) self.assertCodeEqual(join.as_source_code(), '"hello"')
def test_string_join_empty(self): join = codegen.StringConcat([]) join = codegen.simplify(join) self.assertCodeEqual(join.as_source_code(), '""')