qrc

    QR code encoder for MoonBit - port of dbuenzli/qrc

    qr-code
    encoder
    barcode
    Download zip
    Author
    Version
    0.1.2
    License
    ISC
    Last updated
    10 days ago
    Downloads
    47

    #qrc — QR code encoder for MoonBit

    Qrc encodes your data into QR codes. It has built-in QR matrix renderers for SVG, ANSI terminal and text.

    This is a MoonBit port of the original OCaml qrc library by Daniel Bünzli.

    #Features

    • ✅ QR code encoding with multiple data modes (numeric, alphanumeric, byte)
    • ✅ Automatic mode detection
    • ✅ Multiple output formats: SVG, ANSI terminal, plain text, compact text
    • ✅ Reed-Solomon error correction with Galois Field arithmetic
    • ✅ No external dependencies
    • ✅ WebAssembly compatible
    • ⚠️ Kanji mode (treated as byte mode)

    #Installation

    moon install bobzhang/qrc

    #Usage

    #Basic Usage

    ///|
    test {
    // Generate a QR code with default settings
    let qr = @bobzhang/qrc.encode("Hello, MoonBit!")

    // Print QR code information
    println(@bobzhang/qrc/render.info(qr))

    // Render as text
    println(@bobzhang/qrc/render.to_text(qr))

    // Render as compact text (using Unicode block characters)
    println(@bobzhang/qrc/render.to_compact_text(qr))

    // Render as SVG
    let svg = @bobzhang/qrc/render.to_svg(qr)
    println(svg)

    // Render as ANSI terminal output (with colors)
    println(@bobzhang/qrc/render.to_ansi(qr))
    }

    #Advanced Usage

    ///|
    test {
    // Generate QR code with specific error correction level
    let qr = @qrc.encode_with_ec("Important data", H)

    // Manual mode detection
    let mode = @qrc.detect_mode("12345") // Returns Mode::Numeric
    let mode2 = @qrc.detect_mode("HELLO WORLD") // Returns Mode::Alphanumeric
    let mode3 = @qrc.detect_mode("Hello, World!")
    // Returns Mode::Byte
    }

    #Data Modes

    The library automatically detects the best encoding mode:

    • Numeric: Only digits 0-9 (most efficient for numbers)
    • Alphanumeric: Digits, uppercase letters A-Z, and symbols $%*+-./:
    • Byte: Any data (UTF-8 encoded)
    • Kanji: Japanese characters (currently treated as byte mode)

    #Error Correction Levels

    • L: ~7% correction capability
    • M: ~15% correction capability (default)
    • Q: ~25% correction capability
    • H: ~30% correction capability

    #Example Output

    QR Code Information: Version: 1 Size: 21x21 Mode: Byte Error Correction: M (~15%) Data: "Hello, MoonBit!" Text representation: ██████████████ ████ ██████████████ ██ ██ ████ ██ ██ ██ ██████ ██ ████ ██ ██████ ██ ██ ██████ ██ ████ ██ ██████ ██ ██ ██████ ██ ████ ██ ██████ ██ ██ ██ ████ ██ ██ ██████████████ ████ ██████████████ ████ ████████████████████████████████████ ...

    #API Reference

    #Core Functions

    • encode(data: String) -> QRCode - Generate QR code with default error correction
    • encode_with_ec(data: String, ec: ErrorCorrectionLevel) -> QRCode - Generate QR code with specific error correction
    • detect_mode(data: String) -> Mode - Detect the best encoding mode for data

    #Rendering Functions

    • @render.to_text(qr: QRCode) -> String - Plain text representation
    • @render.to_compact_text(qr: QRCode) -> String - Compact Unicode representation
    • @render.to_svg(qr: QRCode) -> String - SVG format
    • @render.to_ansi(qr: QRCode) -> String - ANSI terminal with colors
    • @render.info(qr: QRCode) -> String - QR code information

    #Running the Example

    # Clone the repository git clone <repository-url> cd qrc # Run tests moon test # Run the example moon run src

    #Limitations

    This is a functional implementation demonstrating MoonBit capabilities:

    • ✅ Full Reed-Solomon error correction with proper Galois Field arithmetic
    • ✅ Supports all error correction levels (L, M, Q, H)
    • ✅ Proper data formatting with mode indicators and padding
    • ✅ QR version 1 (21x21 modules) with finder patterns and timing patterns
    • ⚠️ Kanji mode is treated as byte mode
    • ⚠️ No format information or version information encoding
    • ⚠️ No masking patterns applied

    The Reed-Solomon implementation includes:
    • Complete GF(256) Galois Field arithmetic
    • Generator polynomial computation
    • Proper error correction codeword generation
    • Data capacity management for different error correction levels

    For production use with higher versions and advanced features, consider extending this implementation.

    #Contributing

    This project demonstrates porting OCaml code to MoonBit. Contributions to improve the implementation are welcome!

    #License

    ISC License - same as the original OCaml library.

    #Acknowledgments

    • Original OCaml qrc library by Daniel Bünzli
    • MoonBit language team for the excellent tooling and documentation

    Version

    type Version = Int

    ErrorCorrectionLevel

    pub(all) enum ErrorCorrectionLevel {
    L
    M
    Q
    H
    } derive(Eq)

    ErrorCorrectionLevel::equal

    ErrorCorrectionLevel::not_equal

    MaskPattern

    pub enum MaskPattern {
    Pattern0
    Pattern1
    Pattern2
    Pattern3
    Pattern4
    Pattern5
    Pattern6
    Pattern7
    } derive(Eq)

    MaskPattern::equal

    fn MaskPattern::equal(MaskPattern, MaskPattern) -> Bool

    MaskPattern::not_equal

    fn MaskPattern::not_equal(x : MaskPattern, y : MaskPattern) -> Bool

    Matrix

    pub struct Matrix {
    size : Int
    modules : Array[Array[Module]]
    }

    Mode

    pub enum Mode {
    Numeric
    Alphanumeric
    Byte
    Kanji
    } derive(Eq)

    Mode::equal

    fn Mode::equal(Mode, Mode) -> Bool

    Mode::not_equal

    fn Mode::not_equal(x : Mode, y : Mode) -> Bool

    Module

    pub enum Module {
    Light
    Dark
    } derive(Eq)

    Module::equal

    fn Module::equal(Module, Module) -> Bool

    Module::not_equal

    fn Module::not_equal(x : Module, y : Module) -> Bool

    QRCode

    pub struct QRCode {
    version : Int
    error_correction : ErrorCorrectionLevel
    mode : Mode
    data : String
    matrix : Matrix
    }

    apply_error_correction

    fn apply_error_correction(data : Array[Int], mode : Mode, version : Int, ec_level : ErrorCorrectionLevel) -> Array[Int]

    apply_mask

    fn apply_mask(matrix : Matrix, pattern : MaskPattern) -> Unit

    choose_best_mask

    fn choose_best_mask(matrix : Matrix, ec_level : ErrorCorrectionLevel) -> MaskPattern

    detect_mode

    fn detect_mode(data : String) -> Mode

    encode

    fn encode(data : String) -> QRCode

    encode_alphanumeric

    fn encode_alphanumeric(data : String) -> Array[Int]

    encode_byte

    fn encode_byte(data : String) -> Array[Int]

    encode_data

    fn encode_data(data : String, mode : Mode) -> Array[Int]

    encode_kanji

    fn encode_kanji(data : String) -> Array[Int]

    encode_numeric

    fn encode_numeric(data : String) -> Array[Int]

    encode_version_info

    fn encode_version_info(version : Int) -> Int

    encode_with_ec

    fn encode_with_ec(data : String, ec : ErrorCorrectionLevel) -> QRCode

    encode_with_mode_and_ec

    fn encode_with_mode_and_ec(data : String, mode : Mode, version : Int, ec : ErrorCorrectionLevel) -> QRCode

    evaluate_mask_penalty

    fn evaluate_mask_penalty(matrix : Matrix) -> Int

    find_minimum_version

    fn find_minimum_version(data : String, mode : Mode, ec_level : ErrorCorrectionLevel) -> Int

    generate_qr

    fn generate_qr(data : String, error_correction : ErrorCorrectionLevel) -> QRCode

    generate_qr_with_mask

    fn generate_qr_with_mask(data : String, error_correction : ErrorCorrectionLevel) -> QRCode

    get_alignment_positions

    fn get_alignment_positions(version : Int) -> Array[Int]

    get_data_capacity

    fn get_data_capacity(version : Int, ec_level : ErrorCorrectionLevel) -> Int

    get_error_correction_codewords

    fn get_error_correction_codewords(version : Int, ec_level : ErrorCorrectionLevel) -> Int

    get_module

    fn get_module(matrix : Matrix, x : Int, y : Int) -> Module

    gf_div

    fn gf_div(a : Int, b : Int) -> Int

    gf_mul

    fn gf_mul(a : Int, b : Int) -> Int

    init_matrix

    fn init_matrix(version : Int) -> Matrix

    is_data_position

    fn is_data_position(matrix : Matrix, x : Int, y : Int) -> Bool

    is_kanji_character

    fn is_kanji_character(c : Int) -> Bool

    make_byte_mode

    fn make_byte_mode() -> Mode

    make_ec_level_h

    fn make_ec_level_h() -> ErrorCorrectionLevel

    make_ec_level_l

    fn make_ec_level_l() -> ErrorCorrectionLevel

    make_ec_level_m

    fn make_ec_level_m() -> ErrorCorrectionLevel

    make_ec_level_q

    fn make_ec_level_q() -> ErrorCorrectionLevel

    make_kanji_mode

    fn make_kanji_mode() -> Mode

    make_mask_pattern_0

    fn make_mask_pattern_0() -> MaskPattern

    new_matrix

    fn new_matrix(size : Int) -> Matrix

    set_module

    fn set_module(matrix : Matrix, x : Int, y : Int, mod : Module) -> Unit

    version_to_size

    fn version_to_size(version : Int) -> Int

    Source Files