Example #1
0
    def __init__(self, file_name=None, **kwargs):
        Container.__init__(self, **kwargs)
        self.file_name = file_name or self.file_name
        self.ensure_valid_file()
        self.style = self.style.lower()
        self.gen_html_string()
        strati = self.html_string.find("background:")
        self.background_color = self.html_string[strati + 12:strati + 19]
        self.gen_code_json()

        self.code = self.gen_colored_lines()
        if self.insert_line_no:
            self.line_numbers = self.gen_line_numbers()
            self.line_numbers.next_to(self.code, direction=LEFT, buff=self.line_no_buff)

        if self.background == "rectangle":
            if self.insert_line_no:
                forground = VGroup(self.code, self.line_numbers)
            else:
                forground = self.code
            self.background_mobject = SurroundingRectangle(forground, buff=self.margin,
                                                           color=self.background_color,
                                                           fill_color=self.background_color,
                                                           stroke_width=0,
                                                           fill_opacity=1, )
            self.background_mobject.round_corners(self.corner_radius)
        else:
            if self.insert_line_no:
                forground = VGroup(self.code, self.line_numbers)
            else:
                forground = self.code

            height = forground.get_height() + 0.1 * 3 + 2 * self.margin
            width = forground.get_width() + 0.1 * 3 + 2 * self.margin

            rrect = RoundedRectangle(corner_radius=self.corner_radius, height=height, width=width,
                                     stroke_width=0,
                                     color=self.background_color, fill_opacity=1)
            button_radius = 0.09
            red_button = Dot(radius=button_radius, stroke_width=0, color='#ff5f56')
            red_button.shift(LEFT * button_radius * 3)
            yellow_button = Dot(radius=button_radius, stroke_width=0, color='#ffbd2e')
            green_button = Dot(radius=button_radius, stroke_width=0, color='#27c93f')
            green_button.shift(RIGHT * button_radius * 3)
            buttons = VGroup(red_button, yellow_button, green_button)
            buttons.shift(
                UP * (height / 2 - 0.1 * 2 - 0.05) + LEFT * (width / 2 - 0.1 * 5 - self.corner_radius / 2 - 0.05))

            self.background_mobject = VGroup(rrect, buttons)
            x = (height - forground.get_height()) / 2 - 0.1 * 3
            self.background_mobject.shift(forground.get_center())
            self.background_mobject.shift(UP * x)

        if self.insert_line_no:
            VGroup.__init__(self, self.background_mobject, self.line_numbers, *self.code, **kwargs)
        else:
            VGroup.__init__(self, self.background_mobject, Dot(fill_opacity=0, stroke_opacity=0), *self.code, **kwargs)

        self.move_to(np.array([0, 0, 0]))
    def get_secant_slope_group(
        self,
        x,
        graph,
        dx=None,
        dx_line_color=None,
        df_line_color=None,
        dx_label=None,
        df_label=None,
        include_secant_line=True,
        secant_line_color=None,
        secant_line_length=10,
    ):
        """
        This method returns a VGroup of (two lines 
        representing dx and df, the labels for dx and 
        df, and the Secant to the Graph/curve at a 
        particular x value.

        Parameters
        ----------
        x (Union[float, int])
            The x value at which the secant enters, and intersects
            the graph for the first time.

        graph (ParametricFunction)
            The curve/graph for which the secant must
            be found.

        dx (Union[float, int])
            The change in x after which the secant exits.

        dx_line_color (str)
            The line color for the line that indicates the change in x.

        df_line_color (str)
            The line color for the line that indicates the change in y.

        dx_label (str)
            The label to be provided for the change in x.

        df_label (str)
            The label to be provided for the change in y.

        include_secant_line (bool=True)
            Whether or not to include the secant line in the graph,
            or just have the df and dx lines and labels.

        secant_line_color (str)
            The color of the secant line.

        secant_line_length (Union[float,int=10])
            How long the secant line should be.

        Returns:
        --------
        VGroup
            Resulting group is of the form VGroup(
                dx_line,
                df_line,
                dx_label, (if applicable)
                df_label, (if applicable)
                secant_line, (if applicable)
            )
            with attributes of those names.
        """
        kwargs = locals()
        kwargs.pop("self")
        group = VGroup()
        group.kwargs = kwargs

        dx = dx or float(self.x_max - self.x_min) / 10
        dx_line_color = dx_line_color or self.default_input_color
        df_line_color = df_line_color or graph.get_color()

        p1 = self.input_to_graph_point(x, graph)
        p2 = self.input_to_graph_point(x + dx, graph)
        interim_point = p2[0] * RIGHT + p1[1] * UP

        group.dx_line = Line(p1, interim_point, color=dx_line_color)
        group.df_line = Line(interim_point, p2, color=df_line_color)
        group.add(group.dx_line, group.df_line)

        labels = VGroup()
        if dx_label is not None:
            group.dx_label = TexMobject(dx_label)
            labels.add(group.dx_label)
            group.add(group.dx_label)
        if df_label is not None:
            group.df_label = TexMobject(df_label)
            labels.add(group.df_label)
            group.add(group.df_label)

        if len(labels) > 0:
            max_width = 0.8 * group.dx_line.get_width()
            max_height = 0.8 * group.df_line.get_height()
            if labels.get_width() > max_width:
                labels.set_width(max_width)
            if labels.get_height() > max_height:
                labels.set_height(max_height)

        if dx_label is not None:
            group.dx_label.next_to(group.dx_line,
                                   np.sign(dx) * DOWN,
                                   buff=group.dx_label.get_height() / 2)
            group.dx_label.set_color(group.dx_line.get_color())

        if df_label is not None:
            group.df_label.next_to(group.df_line,
                                   np.sign(dx) * RIGHT,
                                   buff=group.df_label.get_height() / 2)
            group.df_label.set_color(group.df_line.get_color())

        if include_secant_line:
            secant_line_color = secant_line_color or self.default_derivative_color
            group.secant_line = Line(p1, p2, color=secant_line_color)
            group.secant_line.scale_in_place(secant_line_length /
                                             group.secant_line.get_length())
            group.add(group.secant_line)

        return group
Example #3
0
    def get_secant_slope_group(
        self,
        x,
        graph,
        dx=None,
        dx_line_color=None,
        df_line_color=None,
        dx_label=None,
        df_label=None,
        include_secant_line=True,
        secant_line_color=None,
        secant_line_length=10,
    ):
        """
        Resulting group is of the form VGroup(
            dx_line,
            df_line,
            dx_label, (if applicable)
            df_label, (if applicable)
            secant_line, (if applicable)
        )
        with attributes of those names.
        """
        kwargs = locals()
        kwargs.pop("self")
        group = VGroup()
        group.kwargs = kwargs

        dx = dx or float(self.x_max - self.x_min) / 10
        dx_line_color = dx_line_color or self.default_input_color
        df_line_color = df_line_color or graph.get_color()

        p1 = self.input_to_graph_point(x, graph)
        p2 = self.input_to_graph_point(x + dx, graph)
        interim_point = p2[0] * RIGHT + p1[1] * UP

        group.dx_line = Line(p1, interim_point, color=dx_line_color)
        group.df_line = Line(interim_point, p2, color=df_line_color)
        group.add(group.dx_line, group.df_line)

        labels = VGroup()
        if dx_label is not None:
            group.dx_label = TexMobject(dx_label)
            labels.add(group.dx_label)
            group.add(group.dx_label)
        if df_label is not None:
            group.df_label = TexMobject(df_label)
            labels.add(group.df_label)
            group.add(group.df_label)

        if len(labels) > 0:
            max_width = 0.8 * group.dx_line.get_width()
            max_height = 0.8 * group.df_line.get_height()
            if labels.get_width() > max_width:
                labels.set_width(max_width)
            if labels.get_height() > max_height:
                labels.set_height(max_height)

        if dx_label is not None:
            group.dx_label.next_to(group.dx_line,
                                   np.sign(dx) * DOWN,
                                   buff=group.dx_label.get_height() / 2)
            group.dx_label.set_color(group.dx_line.get_color())

        if df_label is not None:
            group.df_label.next_to(group.df_line,
                                   np.sign(dx) * RIGHT,
                                   buff=group.df_label.get_height() / 2)
            group.df_label.set_color(group.df_line.get_color())

        if include_secant_line:
            secant_line_color = secant_line_color or self.default_derivative_color
            group.secant_line = Line(p1, p2, color=secant_line_color)
            group.secant_line.scale_in_place(secant_line_length /
                                             group.secant_line.get_length())
            group.add(group.secant_line)

        return group
Example #4
0
    def scroll_through_patrons(self):
        logo_box = Square(side_length=2.5)
        logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF)
        total_width = FRAME_X_RADIUS - logo_box.get_right()[0]

        black_rect = Rectangle(
            fill_color=BLACK,
            fill_opacity=1,
            stroke_width=3,
            stroke_color=BLACK,
            width=FRAME_WIDTH,
            height=0.6 * FRAME_HEIGHT,
        )
        black_rect.to_edge(UP, buff=0)
        line = DashedLine(FRAME_X_RADIUS * LEFT, FRAME_X_RADIUS * RIGHT)
        line.move_to(ORIGIN)

        thanks = TextMobject(self.thanks_words)
        thanks.scale(0.9)
        thanks.next_to(black_rect.get_bottom(), UP, SMALL_BUFF)
        thanks.set_color(YELLOW)
        underline = Line(LEFT, RIGHT)
        underline.match_width(thanks)
        underline.scale(1.1)
        underline.next_to(thanks, DOWN, SMALL_BUFF)
        thanks.add(underline)

        changed_patron_names = map(
            self.modify_patron_name,
            self.specific_patrons,
        )
        patrons = VGroup(*map(
            TextMobject,
            changed_patron_names,
        ))
        patrons.scale(self.patron_scale_val)
        for patron in patrons:
            if patron.get_width() > self.max_patron_width:
                patron.set_width(self.max_patron_width)
        columns = VGroup(*[
            VGroup(*patrons[i::self.n_patron_columns])
            for i in range(self.n_patron_columns)
        ])
        for column in columns:
            for n, name in enumerate(column):
                name.shift(n * self.name_y_spacing * DOWN)
        columns.arrange(
            RIGHT, buff=LARGE_BUFF,
            aligned_edge=UP,
        )
        max_width = FRAME_WIDTH - 1
        if columns.get_width() > max_width:
            columns.set_width(max_width)
        underline.match_width(columns)
        # thanks.to_edge(RIGHT, buff=MED_SMALL_BUFF)
        columns.next_to(underline, DOWN, buff=2)

        columns.generate_target()
        columns.target.to_edge(DOWN, buff=2)
        vect = columns.target.get_center() - columns.get_center()
        distance = get_norm(vect)
        wait_time = 20
        always_shift(
            columns,
            direction=normalize(vect),
            rate=(distance / wait_time)
        )

        self.add(columns, black_rect, line, thanks)
        self.wait(wait_time)
Example #5
0
    def construct(self):
        # Add title
        title = self.title = TextMobject("Clicky Stuffs")
        title.scale(1.5)
        title.to_edge(UP, buff=MED_SMALL_BUFF)

        pi_creatures = VGroup(Randolph(), Mortimer())
        for pi, vect in zip(pi_creatures, [LEFT, RIGHT]):
            pi.set_height(title.get_height())
            pi.change_mode("thinking")
            pi.look(DOWN)
            pi.next_to(title, vect, buff=MED_LARGE_BUFF)
        self.add(title, pi_creatures)

        # Set the top of the screen
        logo_box = Square(side_length=2.5)
        logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF)

        black_rect = Rectangle(
            fill_color=BLACK,
            fill_opacity=1,
            stroke_width=3,
            stroke_color=BLACK,
            width=FRAME_WIDTH,
            height=0.6 * FRAME_HEIGHT,
        )
        black_rect.to_edge(UP, buff=0)
        line = DashedLine(FRAME_X_RADIUS * LEFT, FRAME_X_RADIUS * RIGHT)
        line.move_to(ORIGIN)

        # Add thanks
        thanks = TextMobject(self.thanks_words)
        thanks.scale(0.9)
        thanks.next_to(black_rect.get_bottom(), UP, SMALL_BUFF)
        thanks.set_color(YELLOW)
        underline = Line(LEFT, RIGHT)
        underline.match_width(thanks)
        underline.scale(1.1)
        underline.next_to(thanks, DOWN, SMALL_BUFF)
        thanks.add(underline)

        # Build name list
        file_name = os.path.join(get_directories()["data"], "patrons.txt")
        with open(file_name, "r") as fp:
            names = [
                self.modify_patron_name(name.strip())
                for name in fp.readlines()
            ]

        if self.randomize_order:
            random.shuffle(names)
        else:
            names.sort()

        name_labels = VGroup(*map(TextMobject, names))
        name_labels.scale(self.patron_scale_val)
        for label in name_labels:
            if label.get_width() > self.max_patron_width:
                label.set_width(self.max_patron_width)
        columns = VGroup(*[
            VGroup(*name_labels[i::self.n_patron_columns])
            for i in range(self.n_patron_columns)
        ])
        column_x_spacing = 0.5 + max([c.get_width() for c in columns])

        for i, column in enumerate(columns):
            for n, name in enumerate(column):
                name.shift(n * self.name_y_spacing * DOWN)
                name.align_to(ORIGIN, LEFT)
            column.move_to(i * column_x_spacing * RIGHT, UL)
        columns.center()

        max_width = FRAME_WIDTH - 1
        if columns.get_width() > max_width:
            columns.set_width(max_width)
        underline.match_width(columns)
        columns.next_to(underline, DOWN, buff=3)

        # Set movement
        columns.generate_target()
        distance = columns.get_height() + 2
        wait_time = self.scroll_time
        frame = self.camera.frame
        frame_shift = ApplyMethod(
            frame.shift,
            distance * DOWN,
            run_time=wait_time,
            rate_func=linear,
        )
        blink_anims = []
        blank_mob = Mobject()
        for x in range(wait_time):
            if random.random() < 0.25:
                blink_anims.append(Blink(random.choice(pi_creatures)))
            else:
                blink_anims.append(Animation(blank_mob))
        blinks = Succession(*blink_anims)

        static_group = VGroup(black_rect, line, thanks, pi_creatures, title)
        static_group.fix_in_frame()
        self.add(columns, static_group)
        self.play(frame_shift, blinks)
Example #6
0
    def get_secant_slope_group(
        self,
        x, graph,
        dx=None,
        dx_line_color=None,
        df_line_color=None,
        dx_label=None,
        df_label=None,
        include_secant_line=True,
        secant_line_color=None,
        secant_line_length=10,
    ):
        """
        Resulting group is of the form VGroup(
            dx_line,
            df_line,
            dx_label, (if applicable)
            df_label, (if applicable)
            secant_line, (if applicable)
        )
        with attributes of those names.
        """
        kwargs = locals()
        kwargs.pop("self")
        group = VGroup()
        group.kwargs = kwargs

        dx = dx or float(self.x_max - self.x_min) / 10
        dx_line_color = dx_line_color or self.default_input_color
        df_line_color = df_line_color or graph.get_color()

        p1 = self.input_to_graph_point(x, graph)
        p2 = self.input_to_graph_point(x + dx, graph)
        interim_point = p2[0] * RIGHT + p1[1] * UP

        group.dx_line = Line(
            p1, interim_point,
            color=dx_line_color
        )
        group.df_line = Line(
            interim_point, p2,
            color=df_line_color
        )
        group.add(group.dx_line, group.df_line)

        labels = VGroup()
        if dx_label is not None:
            group.dx_label = TexMobject(dx_label)
            labels.add(group.dx_label)
            group.add(group.dx_label)
        if df_label is not None:
            group.df_label = TexMobject(df_label)
            labels.add(group.df_label)
            group.add(group.df_label)

        if len(labels) > 0:
            max_width = 0.8 * group.dx_line.get_width()
            max_height = 0.8 * group.df_line.get_height()
            if labels.get_width() > max_width:
                labels.set_width(max_width)
            if labels.get_height() > max_height:
                labels.set_height(max_height)

        if dx_label is not None:
            group.dx_label.next_to(
                group.dx_line,
                np.sign(dx) * DOWN,
                buff=group.dx_label.get_height() / 2
            )
            group.dx_label.set_color(group.dx_line.get_color())

        if df_label is not None:
            group.df_label.next_to(
                group.df_line,
                np.sign(dx) * RIGHT,
                buff=group.df_label.get_height() / 2
            )
            group.df_label.set_color(group.df_line.get_color())

        if include_secant_line:
            secant_line_color = secant_line_color or self.default_derivative_color
            group.secant_line = Line(p1, p2, color=secant_line_color)
            group.secant_line.scale_in_place(
                secant_line_length / group.secant_line.get_length()
            )
            group.add(group.secant_line)

        return group
Example #7
0
class Code(VGroup):
    CONFIG = {
        "tab_width": 1,
        "line_spacing": 0.3,  # space between the lines
        "scale_factor": 0.4,
        "run_time": 1,
        #"font": 'Monospac821 BT',
        #"font": 'Arial',
        #"font": "DejaVu Sans Mono",
        "font": "Courier New",
        #"font": 'Courier New',
        "font_size": 48,
        'stroke_width': 0,
        'margin': 0.3,
        'indentation_char': " ",
        "background": "window",  #rectangle or window
        "corner_radius": 0.2,
        'insert_line_no': True,
        'line_no_from': 1,
        "line_no_buff": 0.4,
        'style':
        'railscasts',  #white based:railscasts, vim , material, native; black based: tango, xcode ;
        #pink-based: paraiso-light; styles not highlithing print() and list(): monokai, fruity, paraiso-dark
        #grey-based: arduino, solarized-dark, solarized-light
        #beige-based: inkpot, zenburn
        'language': 'python',
        'generate_html_file': False,
        'adapting_x': False,
        'adapting_y': False,
        'center_y': True,
    }

    def __init__(self, file_name=None, code_str=None, **kwargs):
        Container.__init__(self, **kwargs)
        self.file_name = file_name
        self.code_str = code_str
        self.ensure_valid_file()
        self.style = self.style.lower()
        self.gen_html_string()
        strati = self.html_string.find("background:")
        self.background_color = self.html_string[strati + 12:strati + 19]
        self.gen_code_json()

        self.code = self.gen_colored_lines()

        if self.insert_line_no:
            self.line_numbers = self.gen_line_numbers()
            self.line_numbers.next_to(self.code,
                                      direction=LEFT,
                                      buff=self.line_no_buff)

        if self.background == "rectangle":
            if self.insert_line_no:
                forground = VGroup(self.code, self.line_numbers)
            else:
                forground = self.code
            self.background_mobject = SurroundingRectangle(
                forground,
                buff=self.margin,
                color=self.background_color,
                fill_color=self.background_color,
                stroke_width=0,
                fill_opacity=1,
            )

            self.background_mobject.round_corners(self.corner_radius)
        else:
            if self.insert_line_no:
                forground = VGroup(self.code, self.line_numbers)
            else:
                forground = self.code

            height = forground.get_height() + 0.1 * 3 + 2 * self.margin
            width = forground.get_width() + 0.1 * 3 + 2 * self.margin

            rrect = RoundedRectangle(corner_radius=self.corner_radius,
                                     height=height,
                                     width=width,
                                     stroke_width=0,
                                     color=GREY_E,
                                     fill_opacity=1)
            red_button = Dot(radius=0.1, stroke_width=0, color='#ff5f56')
            red_button.shift(LEFT * 0.1 * 3)
            yellow_button = Dot(radius=0.1, stroke_width=0, color='#ffbd2e')
            green_button = Dot(radius=0.1, stroke_width=0, color='#27c93f')
            green_button.shift(RIGHT * 0.1 * 3)
            buttons = VGroup(red_button, yellow_button, green_button)
            buttons.shift(
                UP * (height / 2 - 0.1 * 2 - 0.05) + LEFT *
                (width / 2 - 0.1 * 5 - self.corner_radius / 2 - 0.05))

            self.background_mobject = VGroup(rrect, buttons)
            x = (height - forground.get_height()) / 2 - 0.1 * 3
            self.background_mobject.shift(forground.get_center())
            self.background_mobject.shift(UP * x)

        if self.insert_line_no:
            VGroup.__init__(self, self.background_mobject, self.line_numbers,
                            *self.code, **kwargs)
        else:
            VGroup.__init__(self, self.background_mobject,
                            Dot(fill_opacity=0, stroke_opacity=0), *self.code,
                            **kwargs)

        window = RIGHT_SIDE[0] - LEFT_SIDE[0]
        width = self.background_mobject.get_width()
        print(width)
        scale_x = window / width * 0.96

        window = TOP[1] - BOTTOM[1]
        print(window)
        width = self.background_mobject.get_height()
        scale_y = window / width * 0.96

        if self.adapting_x and scale_x < scale_y:
            self.scale(scale_x)
        if self.adapting_y and scale_y <= scale_x:
            self.scale(scale_y)
        self.align_to(LEFT_SIDE + self.margin, LEFT)
        self.align_to(
            TOP - self.margin + 0.42 *
            (self.code.char_height + self.code.line_spacing) *
            self.scale_factor, UP)

    def FadeInWindow(self):
        return FadeIn(self.background_mobject),

    '''
    def Write(self):
        write_code = [Write(line) for line in self.code.lines[0]]
        write_line_numbers = [Write(number) for number in self.line_numbers.lines[0]]
        write_all = [item for sublist in zip(write_line_numbers, write_code) for item in sublist]
        return write_all
    def ShowCreation(self):
        write_code = [ShowCreation(line, duration= 1) for line in self.code.lines[0]]
        write_line_numbers = [ShowCreation(number) for number in self.line_numbers.lines[0]]
        write_all = [item for sublist in zip(write_line_numbers, write_code) for item in sublist]

        return write_all
    '''

    def center_to_code(self):
        if self.center_y:
            print(self.get_y() - self.code.lines[0][0].get_height() +
                  self.code.line_spacing)
            self.set_y(self.get_y() +
                       (self.code.char_height + self.code.line_spacing) *
                       self.scale_factor)

    def apply_points_function_about_point(self,
                                          func,
                                          about_point=None,
                                          about_edge=None):
        if about_point is None:
            if about_edge is None:
                about_edge = self.get_corner(UP + LEFT)
            about_point = self.get_critical_point(about_edge)
        for mob in self.family_members_with_points():
            mob.points -= about_point
            mob.points = func(mob.points)
            mob.points += about_point
        return self

    def ensure_valid_file(self):
        if not self.file_name is None:
            possible_paths = [
                os.path.join(os.path.join("assets", "codes"), self.file_name),
                self.file_name,
            ]
            for path in possible_paths:
                if os.path.exists(path):
                    self.file_path = path
                    return
            raise IOError("No file matching %s in codes directory" %
                          self.file_name)

    def gen_line_numbers(self):
        line_numbers_array = []
        for line_no in range(0, self.code_json.__len__()):
            number = str(self.line_no_from + line_no)
            line_numbers_array.append(number)
        #color  ="#E6E8E8"
        line_numbers = Paragraph(
            *[i for i in line_numbers_array],
            line_spacing=self.line_spacing,
            alignment="left",
            font=self.font,
            stroke_width=self.stroke_width,
        ).scale(self.scale_factor)
        return line_numbers

    def gen_colored_lines(self):

        lines_text = []
        for line_no in range(0, self.code_json.__len__()):
            line_str = ""
            for word_index in range(self.code_json[line_no].__len__()):
                line_str = line_str + self.code_json[line_no][word_index][0]
            lines_text.append(self.tab_spaces[line_no] * "\t" + line_str)
        #print(lines_text)
        code = Paragraph(*[text for text in lines_text],
                         line_spacing=self.line_spacing,
                         tab_width=self.tab_width,
                         alignment="left",
                         font=self.font,
                         stroke_width=self.stroke_width,
                         unpack_groups=True).scale(self.scale_factor)
        for line_no in range(code.__len__()):
            line = code[line_no]
            line_char_index = self.tab_spaces[line_no]
            for word_index in range(self.code_json[line_no].__len__()):
                line[line_char_index:line_char_index + self.
                     code_json[line_no][word_index][0].__len__()].set_color(
                         self.code_json[line_no][word_index][1])
                line_char_index += self.code_json[line_no][word_index][
                    0].__len__()
        #print(self.code_json)
        return code

    def gen_html_string(self):
        if self.file_name:
            file = open(self.file_path, "r")
            code_str = file.read()
            file.close()
        if self.code_str:
            code_str = self.code_str
        self.html_string = hilite_me(
            code_str, self.language, {}, self.style, self.insert_line_no,
            "border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"
        )

        if self.generate_html_file:
            os.makedirs(os.path.join("assets", "codes",
                                     "generated_html_files"),
                        exist_ok=True)
            file = open(
                os.path.join("assets", "codes", "generated_html_files",
                             self.file_name + ".html"), "w")
            file.write(self.html_string)
            file.close()

    def gen_code_json(self):
        #print(self.html_string)
        if self.background_color == "#111111" or \
                self.background_color == "#272822" or \
                self.background_color == "#202020" or \
                self.background_color == "#000000":
            self.default_color = "#ffffff"
        else:
            self.default_color = "#000000"

        for i in range(3, -1, -1):
            self.html_string = self.html_string.replace("</" + " " * i, "</")
        for i in range(10, -1, -1):
            self.html_string = self.html_string.replace(
                "</span>" + " " * i, " " * i + "</span>")

        self.html_string = self.html_string.replace("background-color:",
                                                    "background:")

        if self.insert_line_no:
            start_point = self.html_string.find("</td><td><pre")
            start_point = start_point + 9
        else:
            start_point = self.html_string.find("<pre")
        self.html_string = self.html_string[start_point:]
        # print(self.html_string)
        lines = self.html_string.split("\n")
        lines = lines[0:lines.__len__() - 2]
        start_point = lines[0].find(">")
        lines[0] = lines[0][start_point + 1:]
        # print(lines)
        self.code_json = []
        self.tab_spaces = []
        code_json_line_index = -1
        #print(self.html_string)
        starting_string = ""
        for line_index in range(0, lines.__len__()):
            if lines[line_index].__len__() == 0:
                continue
            #print(lines[line_index])
            self.code_json.append([])
            code_json_line_index = code_json_line_index + 1
            if lines[line_index].startswith(self.indentation_char):
                start_point = lines[line_index].find("<")
                starting_string = lines[line_index][:start_point]
                indentation_char_count = lines[line_index][:start_point].count(
                    self.indentation_char)
                if starting_string.__len__(
                ) != indentation_char_count * self.indentation_char.__len__():
                    lines[line_index] = "\t" * indentation_char_count + starting_string[starting_string.rfind(
                        self.indentation_char) + self.indentation_char.__len__():] + \
                                        lines[line_index][start_point:]
                else:
                    lines[line_index] = "\t" * indentation_char_count + lines[
                        line_index][start_point:]

            indentation_char_count = 0
            while lines[line_index][indentation_char_count] == '\t':
                indentation_char_count = indentation_char_count + 1
            self.tab_spaces.append(indentation_char_count)
            # print(lines[line_index])
            lines[line_index] = self.correct_non_span(lines[line_index])
            # print(lines[line_index])
            words = lines[line_index].split("<span")
            for word_index in range(1, words.__len__()):
                color_index = words[word_index].find("color:")
                if color_index == -1:
                    color = self.default_color
                else:
                    starti = words[word_index][color_index:].find("#")
                    color = words[word_index][color_index +
                                              starti:color_index + starti + 7]

                start_point = words[word_index].find(">")
                end_point = words[word_index].find("</span>")
                text = words[word_index][start_point + 1:end_point]
                text = html.unescape(text)
                if text != "":
                    #print(text, "'" + color + "'")
                    self.code_json[code_json_line_index].append([text, color])
        #print(self.code_json)

    def correct_non_span(self, line_str):
        words = line_str.split("</span>")
        line_str = ""
        for i in range(0, words.__len__()):
            if i != words.__len__() - 1:
                j = words[i].find("<span")
            else:
                j = words[i].__len__()
            temp = ""
            starti = -1
            for k in range(0, j):
                if words[i][k] == "\t" and starti == -1:
                    continue
                else:
                    if starti == -1: starti = k
                    temp = temp + words[i][k]
            if temp != "":
                if i != words.__len__() - 1:
                    temp = '<span style="color:' + self.default_color + '">' + words[
                        i][starti:j] + "</span>"
                else:
                    temp = '<span style="color:' + self.default_color + '">' + words[
                        i][starti:j]
                temp = temp + words[i][j:]
                words[i] = temp
            if words[i] != "":
                line_str = line_str + words[i] + "</span>"
        return line_str
Example #8
0
    def __init__(self, file_name=None, code_str=None, **kwargs):
        Container.__init__(self, **kwargs)
        self.file_name = file_name
        self.code_str = code_str
        self.ensure_valid_file()
        self.style = self.style.lower()
        self.gen_html_string()
        strati = self.html_string.find("background:")
        self.background_color = self.html_string[strati + 12:strati + 19]
        self.gen_code_json()

        self.code = self.gen_colored_lines()

        if self.insert_line_no:
            self.line_numbers = self.gen_line_numbers()
            self.line_numbers.next_to(self.code,
                                      direction=LEFT,
                                      buff=self.line_no_buff)

        if self.background == "rectangle":
            if self.insert_line_no:
                forground = VGroup(self.code, self.line_numbers)
            else:
                forground = self.code
            self.background_mobject = SurroundingRectangle(
                forground,
                buff=self.margin,
                color=self.background_color,
                fill_color=self.background_color,
                stroke_width=0,
                fill_opacity=1,
            )

            self.background_mobject.round_corners(self.corner_radius)
        else:
            if self.insert_line_no:
                forground = VGroup(self.code, self.line_numbers)
            else:
                forground = self.code

            height = forground.get_height() + 0.1 * 3 + 2 * self.margin
            width = forground.get_width() + 0.1 * 3 + 2 * self.margin

            rrect = RoundedRectangle(corner_radius=self.corner_radius,
                                     height=height,
                                     width=width,
                                     stroke_width=0,
                                     color=GREY_E,
                                     fill_opacity=1)
            red_button = Dot(radius=0.1, stroke_width=0, color='#ff5f56')
            red_button.shift(LEFT * 0.1 * 3)
            yellow_button = Dot(radius=0.1, stroke_width=0, color='#ffbd2e')
            green_button = Dot(radius=0.1, stroke_width=0, color='#27c93f')
            green_button.shift(RIGHT * 0.1 * 3)
            buttons = VGroup(red_button, yellow_button, green_button)
            buttons.shift(
                UP * (height / 2 - 0.1 * 2 - 0.05) + LEFT *
                (width / 2 - 0.1 * 5 - self.corner_radius / 2 - 0.05))

            self.background_mobject = VGroup(rrect, buttons)
            x = (height - forground.get_height()) / 2 - 0.1 * 3
            self.background_mobject.shift(forground.get_center())
            self.background_mobject.shift(UP * x)

        if self.insert_line_no:
            VGroup.__init__(self, self.background_mobject, self.line_numbers,
                            *self.code, **kwargs)
        else:
            VGroup.__init__(self, self.background_mobject,
                            Dot(fill_opacity=0, stroke_opacity=0), *self.code,
                            **kwargs)

        window = RIGHT_SIDE[0] - LEFT_SIDE[0]
        width = self.background_mobject.get_width()
        print(width)
        scale_x = window / width * 0.96

        window = TOP[1] - BOTTOM[1]
        print(window)
        width = self.background_mobject.get_height()
        scale_y = window / width * 0.96

        if self.adapting_x and scale_x < scale_y:
            self.scale(scale_x)
        if self.adapting_y and scale_y <= scale_x:
            self.scale(scale_y)
        self.align_to(LEFT_SIDE + self.margin, LEFT)
        self.align_to(
            TOP - self.margin + 0.42 *
            (self.code.char_height + self.code.line_spacing) *
            self.scale_factor, UP)
Example #9
0
    def scroll_through_patrons(self):
        logo_box = Square(side_length=2.5)
        logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF)
        total_width = FRAME_X_RADIUS - logo_box.get_right()[0]

        black_rect = Rectangle(
            fill_color=BLACK,
            fill_opacity=1,
            stroke_width=3,
            stroke_color=BLACK,
            width=FRAME_WIDTH,
            height=0.6 * FRAME_HEIGHT,
        )
        black_rect.to_edge(UP, buff=0)
        line = DashedLine(FRAME_X_RADIUS * LEFT, FRAME_X_RADIUS * RIGHT)
        line.move_to(ORIGIN)

        thanks = TextMobject(self.thanks_words)
        thanks.scale(0.9)
        thanks.next_to(black_rect.get_bottom(), UP, SMALL_BUFF)
        thanks.set_color(YELLOW)
        underline = Line(LEFT, RIGHT)
        underline.match_width(thanks)
        underline.scale(1.1)
        underline.next_to(thanks, DOWN, SMALL_BUFF)
        thanks.add(underline)

        changed_patron_names = map(
            self.modify_patron_name,
            self.specific_patrons,
        )
        patrons = VGroup(*map(
            TextMobject,
            changed_patron_names,
        ))
        patrons.scale(self.patron_scale_val)
        for patron in patrons:
            if patron.get_width() > self.max_patron_width:
                patron.set_width(self.max_patron_width)
        columns = VGroup(*[
            VGroup(*patrons[i::self.n_patron_columns])
            for i in range(self.n_patron_columns)
        ])
        for column in columns:
            for n, name in enumerate(column):
                name.shift(n * self.name_y_spacing * DOWN)
        columns.arrange(
            RIGHT, buff=LARGE_BUFF,
            aligned_edge=UP,
        )
        if columns.get_width() > self.max_patron_width:
            columns.set_width(total_width - 1)

        thanks.to_edge(RIGHT, buff=MED_SMALL_BUFF)
        columns.next_to(underline, DOWN, buff=2)

        columns.generate_target()
        columns.target.to_edge(DOWN, buff=2)
        vect = columns.target.get_center() - columns.get_center()
        distance = get_norm(vect)
        wait_time = 20
        always_shift(
            columns,
            direction=normalize(vect),
            rate=(distance / wait_time)
        )

        self.add(columns, black_rect, line, thanks)
        self.wait(wait_time)