Skip to content

Instantly share code, notes, and snippets.

@new-xmon-df
Created March 29, 2024 05:56
Show Gist options
  • Save new-xmon-df/a8a4bc2bf6c999316c15dc65f199f41c to your computer and use it in GitHub Desktop.
Save new-xmon-df/a8a4bc2bf6c999316c15dc65f199f41c to your computer and use it in GitHub Desktop.

Revisions

  1. new-xmon-df created this gist Mar 29, 2024.
    44 changes: 44 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,44 @@
    # KiCad Symbol to Library Converter (.kicad_sym to .lib)

    This Python script converts KiCad symbol files (.kicad_sym) into a symbol library (.lib), simplifying the integration of new components into your KiCad projects.

    ## Features

    - **Automated Conversion**: The script analyzes .kicad_sym files and generates KiCad-compatible .lib files.
    - **Data Preservation**: Preserves essential symbol information such as names, connection points, and properties.
    - **Simple Interface**: Easy to use via the command line.

    ## Requirements

    - Python 3.x
    - `sexpdata` package (installable via `pip install sexpdata`)

    ## Usage

    1. Clone or download this repository to your local machine.
    2. Ensure you have Python 3.x installed on your system.
    3. Install the `sexpdata` package using the following command:

    ```bash
    pip install sexpdata
    ```
    4. Run the script by providing the .kicad_sym file you want to convert, replace input_file.kicad_sym with the path and name of your .kicad_sym file, and output_file.lib with the desired name for the resulting .lib file.:
    ```bash
    python3 sym2lib.py input_file.kicad_sym > output_file.lib
    ```

    5. The resulting .lib file will be available in the specified directory.



    _Please note that the use of this script is at your own risk. The author takes no responsibility for any consequences arising from its usage._

    ## Contributions

    Contributions are welcome! If you find any bugs or have ideas for improvements, feel free to open an issue or submit a pull request.

    ## License

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


    105 changes: 105 additions & 0 deletions kicadsym2lib.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,105 @@
    import sys

    from sexpdata import loads, dumps, Symbol

    lib_header = """EESchema-LIBRARY Version 2.4
    #encoding utf-8"""

    lib_footer = """#
    #End Library"""

    symbol_header = """#
    # {NAME}
    #
    DEF {NAME} U 0 40 Y Y 1 F N
    F0 "U" 0 -250 60 H V C CNN
    F1 "{NAME}" 0 -350 60 H V C CNN
    F2 "" 0 0 50 H I C CNN
    F3 "" 0 0 50 H I C CNN
    DRAW"""

    symbol_footer = """ENDDRAW
    ENDDEF
    """


    def read_data(path):
    with open(path) as f:
    return f.read()


    symbol_pts = Symbol('pts')
    symbol_xy = Symbol('xy')

    def write_polyline(pts):
    if pts[0] == symbol_pts:
    points = []
    for xy in pts[1:]:
    if xy[0] == symbol_xy:
    x = xy[1] / 0.0254
    y = xy[2] / 0.0254
    points.append("{:.0f} {:.0f}".format(x, y))
    print("P {COUNT} 0 1 0 {POINTS} N".format(
    COUNT=len(points), POINTS=" ".join(points)))


    def write_pin(pin):
    t = {"input": "I", "output": "O", "bidirectional": "B", "power_in": "W"}[pin[1].value()]
    name = ""
    for p in pin[3:]:
    if isinstance(p, list):
    tag = p[0].value()
    if tag == "at":
    x = int(p[1] / 0.0254)
    y = int(p[2] / 0.0254)
    direction = {90: "U", 0: "R", 270: "D", 180: "L"}[p[3]]
    elif tag == "length":
    length = int(p[1] / 0.0254)
    elif tag == "name":
    name = p[1]
    height1 = 50
    elif tag == "number":
    number = p[1]
    height2 = 50
    if name != "":
    s = "X {NAME} {NUMBER} {X} {Y} {LENGTH} {DIRECTION} {HEIGHT1} {HEIGHT2} 1 1 {TYPE}".format(
    NAME=name, NUMBER=number, X=x, Y=y, LENGTH=length,
    DIRECTION=direction, HEIGHT1=height1, HEIGHT2=height2, TYPE=t)
    print(s)



    def main():
    if len(sys.argv) != 2:
    print("Pass kicad_sym file to convert")
    return
    path = sys.argv[1]
    data = read_data(path)

    symbol_tag = Symbol('symbol')
    symbol_rectangle = Symbol('rectangle')
    symbol_polyline = Symbol('polyline')
    symbol_pin = Symbol('pin')

    s = loads(data)

    print(lib_header)

    for symbol in s[3:]:
    if symbol[0] == symbol_tag:
    name = symbol[1].split(' ')[0] # Ajuste para extraer solo el nombre del símbolo
    header = symbol_header.format(NAME=name)
    print(header)
    for elem in symbol[3:]:
    if elem[0] == symbol_tag:
    for items in elem[2:]:
    if items[0] == symbol_rectangle:
    continue
    elif items[0] == symbol_polyline:
    write_polyline(items[1])
    elif items[0] == symbol_pin:
    write_pin(items)
    print(symbol_footer)
    print(lib_footer)

    main()