fn next()

in highlight/src/lib.rs [732:848]


    fn next(&mut self) -> Option<Self::Item> {
        if let Some(cancellation_flag) = self.cancellation_flag {
            self.operation_count += 1;
            if self.operation_count >= CANCELLATION_CHECK_INTERVAL {
                self.operation_count = 0;
                if cancellation_flag.load(Ordering::Relaxed) != 0 {
                    return Some(Err(Error::Cancelled));
                }
            }
        }

        if let Some(utf8_error_len) = self.utf8_error_len.take() {
            self.source_offset += utf8_error_len;
            return Some(Ok(HighlightEvent::Source("\u{FFFD}")));
        }

        while !self.layers.is_empty() {
            let mut scope_event = None;
            let first_layer = &self.layers[0];

            // If the current layer is not covered up by a nested layer, then
            // process any scope boundaries and language injections for the layer's
            // current position.
            let first_layer_is_visible = first_layer.depth >= self.max_opaque_layer_depth;
            if first_layer_is_visible {
                let local_highlight = first_layer.local_highlight;
                let properties = &first_layer.cursor.node_properties();

                // Add any injections for the current node.
                if !first_layer.at_node_end {
                    let node = first_layer.cursor.node();
                    let injections = properties
                        .injections
                        .iter()
                        .filter_map(
                            |Injection {
                                 language,
                                 content,
                                 includes_children,
                             }| {
                                if let Some(language) =
                                    self.injection_language_string(&node, language)
                                {
                                    let nodes = self.nodes_for_tree_path(node, content);
                                    let ranges = Self::intersect_ranges(
                                        &first_layer.ranges,
                                        &nodes,
                                        *includes_children,
                                    );
                                    if ranges.len() > 0 {
                                        return Some((language, ranges, *includes_children));
                                    }
                                }
                                None
                            },
                        )
                        .collect::<Vec<_>>();

                    let depth = first_layer.depth + 1;
                    for (language, ranges, includes_children) in injections {
                        if let Some(error) =
                            self.add_layer(&language, ranges, depth, includes_children)
                        {
                            return Some(Err(error));
                        }
                    }
                }

                // Determine if any scopes start or end at the current position.
                let first_layer = &mut self.layers[0];
                if let Some(highlight) = local_highlight
                    .or(properties.highlight_nonlocal)
                    .or(properties.highlight)
                {
                    let next_offset = cmp::min(self.source.len(), first_layer.offset());

                    // Before returning any highlight boundaries, return any remaining slice of
                    // the source code the precedes that highlight boundary.
                    if self.source_offset < next_offset {
                        return self.emit_source(next_offset);
                    }

                    scope_event = if first_layer.at_node_end {
                        Some(Ok(HighlightEvent::HighlightEnd))
                    } else {
                        Some(Ok(HighlightEvent::HighlightStart(highlight)))
                    };
                }
            }

            // Advance the current layer's tree cursor. This might cause that cursor to move
            // beyond one of the other layers' cursors for a different syntax tree, so we need
            // to re-sort the layers. If the cursor is already at the end of its syntax tree,
            // remove it.
            if self.layers[0].advance() {
                let mut index = 0;
                while self.layers.get(index + 1).map_or(false, |next| {
                    self.layers[index].cmp(next) == cmp::Ordering::Greater
                }) {
                    self.layers.swap(index, index + 1);
                    index += 1;
                }
            } else {
                self.remove_first_layer();
            }

            if scope_event.is_some() {
                return scope_event;
            }
        }

        if self.source_offset < self.source.len() {
            self.emit_source(self.source.len())
        } else {
            None
        }
    }