Skip to main content

Tree-Sitter Wikitext Parser

PyPI Version npm Version crates.io Version

This repository contains the implementation of a Tree-Sitter parser for Wikitext, a markup language used by MediaWiki.

Try the parse in the playground

Overview

Tree-Sitter is a powerful parser generator tool and incremental parsing library. It is designed to build concrete syntax trees for source files and efficiently update them as the source changes. This project leverages Tree-Sitter to parse Wikitext, enabling structured analysis and manipulation of MediaWiki content.

Features

  • Incremental Parsing: Efficiently updates syntax trees as the source changes.
  • Language Agnostic: Can be embedded in applications written in C, Python, Go, Rust, Node.js, and Swift.
  • Robust Parsing: Handles syntax errors gracefully to provide useful results.
  • Custom Grammar: Implements a grammar tailored for Wikitext.

Repository Structure

  • src/: Contains the core C implementation of the parser.
  • bindings/: Language-specific bindings for Python, Go, Node.js, Rust, and Swift.
  • grammar.js: Defines the grammar for Wikitext.
  • queries/: Contains Tree-Sitter query files for extracting specific syntax patterns.
  • tests/: Unit tests for validating the parser's functionality.

Installation

Prerequisites

  • A C compiler (e.g., GCC or Clang)
  • Node.js (for building the grammar)
  • Python 3.6+ (optional, for Python bindings)

Build Instructions

  1. Clone the repository:

    git clone https://github.com/santhoshtr/tree-sitter-wikitext.git
    cd tree-sitter-wikitext
    
  2. Build the parser:

    npm install
    
  3. (Optional) Build language-specific bindings:

    • Python: Run python setup.py build.
    • Rust: Use cargo build.
    • Go: Use go build.

Usage

Embedding in Applications

The parser can be embedded in applications written in various languages. For example:

  • Python: Use the tree-sitter Python module to load and use the parser.
  • Node.js: Import the parser as a Node.js module.
  • Rust: Use the tree-sitter crate to integrate the parser.

Example: Parsing Wikitext in Python

First, install the required dependencies:

pip install tree-sitter

Then use the parser in your Python code:

from tree_sitter import Language, Parser, Query, QueryCursor
import tree_sitter_wikitext as tswikitext

# Create a language object
WIKITEXT_LANGUAGE = Language(tswikitext.language())

# Create a parser
parser = Parser(WIKITEXT_LANGUAGE)


# Parse some wikitext
source_code = b"""
== Introduction ==
This is a '''bold''' text with ''italic'' formatting.

* List item 1
* List item 2

[[Link to another page]]
"""

tree = parser.parse(source_code)

# Print the syntax tree
print(tree.root_node)

# Walk through the tree
def walk_tree(node, depth=0):
    indent = "  " * depth
    print(f"{indent}{node.type}: {node.text.decode('utf-8')[:50]}")
    for child in node.children:
        walk_tree(child, depth + 1)

walk_tree(tree.root_node)

# Query for specific nodes (e.g., all headings)
query = Query(WIKITEXT_LANGUAGE,
    """
(heading2) @heading
""")

query_cursor = QueryCursor(query)
captures = query_cursor.captures(tree.root_node)
for  capture_name in captures:
    print(f"Found {capture_name}: {captures[capture_name][0].text.decode('utf-8').strip()}")```

### Example: Parsing Wikitext in Node.js

First, install the parser:

```bash
npm install tree-sitter tree-sitter-wikitext

Then use it in your Node.js application:

const Parser = require('tree-sitter');
const Wikitext = require('tree-sitter-wikitext');

// Create a parser
const parser = new Parser();
parser.setLanguage(Wikitext);

// Parse some wikitext
const sourceCode = `
== Introduction ==
This is a '''bold''' text with ''italic'' formatting.

* List item 1
* List item 2

[[Link to another page]]
`;

const tree = parser.parse(sourceCode);

// Print the syntax tree
console.log(tree.rootNode.toString());

// Walk through the tree
function walkTree(node, depth = 0) {
    const indent = "  ".repeat(depth);
    console.log(`${indent}${node.type}: ${node.text.substring(0, 50)}`);

    for (const child of node.children) {
        walkTree(child, depth + 1);
    }
}

walkTree(tree.rootNode);

// Query for specific nodes
const query = Wikitext.query(`
(heading) @heading
(bold) @bold
(italic) @italic
(link) @link
`);

const captures = query.captures(tree.rootNode);
captures.forEach(capture => {
    console.log(`Found ${capture.name}: ${capture.node.text.trim()}`);
});

// Find all headings
function findHeadings(node) {
    const headings = [];

    if (node.type === 'heading') {
        headings.push({
            level: node.children.filter(c => c.type === 'heading_marker')[0]?.text.length || 2,
            text: node.text.replace(/^=+\s*|\s*=+$/g, '').trim()
        });
    }

    for (const child of node.children) {
        headings.push(...findHeadings(child));
    }

    return headings;
}

const headings = findHeadings(tree.rootNode);
console.log('Headings found:', headings);

Advanced Usage in Node.js

For more advanced use cases, you can create incremental parsers and handle large documents:

const Parser = require('tree-sitter');
const Wikitext = require('tree-sitter-wikitext');

class WikitextProcessor {
    constructor() {
        this.parser = new Parser();
        this.parser.setLanguage(Wikitext);
    }

    parseDocument(content) {
        return this.parser.parse(content);
    }

    updateDocument(oldTree, content, startIndex, oldEndIndex, newEndIndex) {
        // For incremental parsing
        oldTree.edit({
            startIndex,
            oldEndIndex,
            newEndIndex,
            startPosition: { row: 0, column: startIndex },
            oldEndPosition: { row: 0, column: oldEndIndex },
            newEndPosition: { row: 0, column: newEndIndex }
        });

        return this.parser.parse(content, oldTree);
    }

    extractMetadata(tree) {
        const metadata = {
            headings: [],
            links: [],
            templates: [],
            categories: []
        };

        // Implementation would depend on your specific grammar rules
        // This is a simplified example
        function traverse(node) {
            switch (node.type) {
                case 'heading':
                    metadata.headings.push(node.text.trim());
                    break;
                case 'link':
                    metadata.links.push(node.text.trim());
                    break;
                // Add more cases based on your grammar
            }

            for (const child of node.children) {
                traverse(child);
            }
        }

        traverse(tree.rootNode);
        return metadata;
    }
}

// Usage
const processor = new WikitextProcessor();
const tree = processor.parseDocument(sourceCode);
const metadata = processor.extractMetadata(tree);
console.log('Document metadata:', metadata);

Example: Parsing Wikitext in Rust

use tree_sitter::{Parser, Language};

fn main() {
    // Create a new parser
    let mut parser = tree_sitter::Parser::new();
    parser.set_language(&tree_sitter_wikitext::LANGUAGE.into()).expect("Error loading wikitext grammar");

    // Parse a Wikitext string
    let source_code = "== Heading ==\nThis is a paragraph.\n";
    let tree = parser.parse(source_code, None).unwrap();

    // Print the syntax tree
    println!("{}", tree.root_node().to_sexp());
}

Using with Neovim

Checkout the repo, add the following configuration to init.lua of your nvim installation.

--- Refer https://github.com/nvim-treesitter/nvim-treesitter
local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
parser_config.wikitext = {
  install_info = {
    url = "~/path/to/tree-sitter-wikitext", -- local path or git repo
    files = { "src/parser.c" }, -- note that some parsers also require src/scanner.c or src/scanner.cc
    -- optional entries:
    branch = "main", -- default branch in case of git repo if different from master
    generate_requires_npm = false, -- if stand-alone parser without npm dependencies
    requires_generate_from_grammar = false, -- if folder contains pre-generated src/parser.c
  },
  filetype = "wikitext", -- if filetype does not match the parser name
}

vim.filetype.add({
  pattern = {
    [".*/*.wikitext"] = "wikitext",
  },
})

Link the queries folder of tree-sitter-wikitext to queries/wikitext folder of nvim

cd ~/.config/nvim
mkdir -p queries
ln -s path/to/tree-sitter-wikitext/queries queries/wikitext

Re-open nvim. Open any file with .wikitext extension. You should see syntax highlighting. You can also inspect the tree-sitter tree using :InspectTree command

To run queries against a buffer, run :EditQuery wikitext. A scratch buffer will be opened. Write your Tree-Sitter query there, in normal node, move cursor over the capture names. You will see the corresponding text in the buffer get highlighted.

Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository.
  2. Create a new branch for your feature or bug fix.
  3. Submit a pull request with a detailed description of your changes.

License

This project is licensed under the MIT License. See the LICENSE.md file for details.

Metadata

Release files for tree-sitter-wikitext 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tree-sitter-wikitext 0.1.3
File Size Uploaded Provenance
tree_sitter_wikitext-0.1.3.tar.gz 98.2 kB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for tree-sitter-wikitext 0.1.3
File
tree_sitter_wikitext-0.1.3-cp39-abi3-win_arm64.whl CPython 3.9 abi3 Windows ARM64 Details
tree_sitter_wikitext-0.1.3-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
tree_sitter_wikitext-0.1.3-cp39-abi3-musllinux_1_2_x86_64.whl CPython 3.9 abi3 Linux musl 1.2+ x86-64 Details
tree_sitter_wikitext-0.1.3-cp39-abi3-musllinux_1_2_aarch64.whl CPython 3.9 abi3 Linux musl 1.2+ ARM64 Details
tree_sitter_wikitext-0.1.3-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64, Linux glibc 2.28+ ARM64 Details
tree_sitter_wikitext-0.1.3-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl CPython 3.9 abi3 Linux glibc 2.28+ x86-64, Linux glibc 2.5+ x86-64 Details
tree_sitter_wikitext-0.1.3-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details
tree_sitter_wikitext-0.1.3-cp39-abi3-macosx_10_9_x86_64.whl CPython 3.9 abi3 macOS 10.9+ x86-64 Details

Total release size: 709.0 kB

Release files / tree_sitter_wikitext-0.1.3.tar.gz

Download URL tree_sitter_wikitext-0.1.3.tar.gz
Size 98.2 kB
Tags Source
SHA-256 checksum
How to use checksums
bf099470ac851d6f5eb2ee07d18ecb48d0f6de9dac5c10b5f363f2347596ec6f
BLAKE2b-256 checksum
How to use checksums
a56d0b3f2b905b2878e8eddf964e5fac4955824f547ae81b1da91fe137ad6f7f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / tree_sitter_wikitext-0.1.3-cp39-abi3-win_arm64.whl

Download URL tree_sitter_wikitext-0.1.3-cp39-abi3-win_arm64.whl
Size 63.8 kB
Tags CPython 3.9 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
dc05bb331ff774a7c32340efcb9714c70ff7c446c1921ac6189d094f98b9a4b0
BLAKE2b-256 checksum
How to use checksums
785be5b1dabac948854fbee7f41e9000acf0bffdaeb236dc75114a1b56b4e818
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / tree_sitter_wikitext-0.1.3-cp39-abi3-win_amd64.whl

Download URL tree_sitter_wikitext-0.1.3-cp39-abi3-win_amd64.whl
Size 65.2 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
79c95ecae05d9fc82afd3e6e1be573d1f68c656d2dad2bff40699c5625749422
BLAKE2b-256 checksum
How to use checksums
f3b654f1d7f8296ecb405082dd3ff75d7e01719038e328fc4598affce8a8c767
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / tree_sitter_wikitext-0.1.3-cp39-abi3-musllinux_1_2_x86_64.whl

Download URL tree_sitter_wikitext-0.1.3-cp39-abi3-musllinux_1_2_x86_64.whl
Size 87.7 kB
Tags CPython 3.9 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
5a734232268590d1dce40a99c0a2cbf4847515803011c8c4cb61b34762ee42f9
BLAKE2b-256 checksum
How to use checksums
354a9c67a868ef984fb85df54cf20ca5e0a1e1c00f33af361a9cb1164f14e4f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / tree_sitter_wikitext-0.1.3-cp39-abi3-musllinux_1_2_aarch64.whl

Download URL tree_sitter_wikitext-0.1.3-cp39-abi3-musllinux_1_2_aarch64.whl
Size 89.0 kB
Tags CPython 3.9 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
51d62657653724fc81687812bb46233d3665629b7053754f5cdd685685fcb883
BLAKE2b-256 checksum
How to use checksums
f2ca79f08097783d6e6e10104ab97271c5c47f93e4ab78e9d41708b7a60e02ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / tree_sitter_wikitext-0.1.3-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl

Download URL tree_sitter_wikitext-0.1.3-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Size 90.2 kB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
9c04449cf1e84f414b7c6df6e2f61c0321c92124e96f5ee3748fbd9ad29e3824
BLAKE2b-256 checksum
How to use checksums
18dd7beee6525ef1f78b849e9e02f4dd177688f567a2d6fee3b3cffa0d7e7b0e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / tree_sitter_wikitext-0.1.3-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl

Download URL tree_sitter_wikitext-0.1.3-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Size 87.8 kB
Tags CPython 3.9 Linux glibc 2.28+ x86-64 Linux glibc 2.5+ x86-64 abi3
SHA-256 checksum
How to use checksums
2870c06bff34b1f9910efd71a14e57a1e5303dee0f5ba8082a7b9108a8bcc866
BLAKE2b-256 checksum
How to use checksums
0fe907acebb638ef57ca242d07666bb6449a663e45accb348b9e2b8ba1b92367
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / tree_sitter_wikitext-0.1.3-cp39-abi3-macosx_11_0_arm64.whl

Download URL tree_sitter_wikitext-0.1.3-cp39-abi3-macosx_11_0_arm64.whl
Size 65.0 kB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
45e2a08fe10257e08a5b5ed1eee89381e8867a27ccfb9212f35c5da48332058d
BLAKE2b-256 checksum
How to use checksums
2e8743a63ec640699e9118d6086adb9f93aeb8bb34dadb4eac018f38f6a3735e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / tree_sitter_wikitext-0.1.3-cp39-abi3-macosx_10_9_x86_64.whl

Download URL tree_sitter_wikitext-0.1.3-cp39-abi3-macosx_10_9_x86_64.whl
Size 61.9 kB
Tags CPython 3.9 abi3 macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
1bc0b4426a3753c7cb5cd8d66d4375f688a61a7a5d09f948b5c3e4ec143f62a2
BLAKE2b-256 checksum
How to use checksums
1182372aa6cf308b8293c7430bc0a97c7ee1e02dbd152fb67a59b4767b0c1bfe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Security for tree-sitter-wikitext 0.1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page