Paclet Development

Extending the Wolfram System

Connor Gray, October 2021

connorg@wolfram.com

What are paclets?

Paclets extend the Wolfram System with new functionality.

Paclets are essentially just a collection of files.

Paclets primarily contain Wolfram Language source code.

Paclets can also contain Palettes, directives changing FrontEnd behavior, etc.

Autocompletions, etc. (FrontEndResources)

Much of the built-in functionality of the Wolfram System is implemented using paclets.

Paclets can be updated automatically.

New Tools in Version 13

DocumentationTools

PacletTools

Coming Soon: Paclet Resource’s and the Wolfram Paclet Repository

Creating a new paclet

Needs["PacletTools`"]

obj=CreatePaclet[
	"ConnorGray__MyPaclet",
	"~/Desktop",
	"WolframVersion"->"12.3+"
]

pacletDirectory=obj["Location"]

SystemOpen[ParentDirectory[pacletDirectory]]

Panel[
		FileTreeDiagram[
			pacletDirectory,
			(*(StringContainsQ[#,"Kernel"|"MyPaclet.wl"])&,*)
			Magnification->2
		],
		"ConnorGray__MyPaclet directory"
	]

Content of a PacletInfo.wl file

Row[{
	Panel[
		FileTreeDiagram[
			PacletObject[File["~/Desktop/ConnorGray__MyPaclet"]]["Location"],
			(StringContainsQ[#,"PacletInfo.wl"])&,
			Magnification->2
		],
		"ConnorGray__MyPaclet directory"
	],
	Spacer[20],Magnify["->",8],Spacer[20],
	Panel[
		Style[
			Framed[ReadString[FileNameJoin[{pacletDirectory,"PacletInfo.wl"}]]]
			,
			FontFamily->"Source Code Pro",FontSize->12
		],
		"PacletInfo.wl"
	]
}]

The PacletInfo.wl file is the programmatic description of what a paclet is, and what files it contains.

“Name”

Panel[
		Style[
			StringStyleReplace[
				ReadString[FileNameJoin[{pacletDirectory,"PacletInfo.wl"}]],
				t:"\"Name\" -> \"ConnorGray__MyPaclet\"":>Style[Framed[t],Darker@Cyan]
			],
			
		],
		"PacletInfo.wl"
	]

“PublisherID”

Panel[
		Style[
			StringStyleReplace[
				ReadString[FileNameJoin[{pacletDirectory,"PacletInfo.wl"}]],
				t:"\"PublisherID\" -> \"ConnorGray\"":>Style[Framed[t],Darker@Cyan]
			],
			
		],
		"PacletInfo.wl"
	]

$PublisherID

“Version”

Panel[
		Style[
			StringStyleReplace[
				ReadString[FileNameJoin[{pacletDirectory,"PacletInfo.wl"}]],
				t:"\"Version\" -> \"0.0.1\"":>Style[Framed[t],Darker@Cyan]
			],
			
		],
		"PacletInfo.wl"
	]

“WolframVersion”

Panel[
		Style[
			StringStyleReplace[
				ReadString[FileNameJoin[{pacletDirectory,"PacletInfo.wl"}]],
				t:"\"WolframVersion\" -> \"13.+\"":>Style[Framed[t],Darker@Cyan]
			],
			
		],
		"PacletInfo.wl"
	]

“Extensions”

Panel[
		Style[
			StringStyleReplace[
				ReadString[FileNameJoin[{pacletDirectory,"PacletInfo.wl"}]],
				t:RegularExpression["\"Extensions\" ->\n.+}"]:>Style[Framed[StringReplace[t,"\n        "->"\n"]],Darker@Cyan]
			],
			
		],
		"PacletInfo.wl"
	]

By default, the only files included in a paclet is the PacletInfo.wl file itself.

Other files are only considered part of a paclet if they are declared in the “Extensions” field of the PacletInfo.wl file.

“Kernel” extensions

Row[{
	Panel[
		Style[
			StringStyleReplace[
				ReadString[FileNameJoin[{pacletDirectory,"PacletInfo.wl"}]],
				t:RegularExpression["{[^{]*\"Kernel\".*},"]:>Style[
					Framed[StringReplace[t,"\n                "->"\n"]],
					Darker@Cyan
				]
			],
			FontFamily->"Source Code Pro",FontSize->12
		],
		"PacletInfo.wl"
	],
	Spacer[20],Magnify["->",8],Spacer[20],
	Panel[
		FileTreeDiagram[
			PacletObject[File["~/Desktop/ConnorGray__MyPaclet"]]["Location"],
			(StringContainsQ[#,"Kernel"|"MyPaclet.wl"])&,
			Magnification->2
		],
		"ConnorGray__MyPaclet directory"
	]
}]

The “Kernel” extension extends the system with new Wolfram Language code.

The “Root” option

Row[{
	Panel[
		Style[
			StringStyleReplace[
				ReadString[FileNameJoin[{pacletDirectory,"PacletInfo.wl"}]],
				t:RegularExpression["\"Root\" -> \"Kernel\""]:>Style[Framed[t],Darker@Cyan]
			],
			
		],
		"PacletInfo.wl"
	],
	Spacer[20],Magnify["->",8],Spacer[20],
	Panel[
		FileTreeDiagram[
			PacletObject[File["~/Desktop/ConnorGray__MyPaclet"]]["Location"],
			(StringContainsQ[#,"Kernel"])&,
			Magnification->2
		],
		"ConnorGray__MyPaclet directory"
	]
}]

Every extension has a default value for the “Root” option, which is typically the name of the extension itself.

For example, the {“FrontEnd”} extension type locates it’s files in the MyPaclet/FrontEnd/ directory by default.

New paclets should always specify a “Root” -> “Kernel” value. Paclets uploaded to the paclet repository are required to do this.

The “Context” option

Row[{
	Panel[
		Style[
			StringStyleReplace[
				ReadString[FileNameJoin[{pacletDirectory,"PacletInfo.wl"}]],
				t:RegularExpression["\"Context\" ->[^}]+}[^}]+}"]:>Style[Framed[StringReplace[t,"\n                    "->"\n"]],Darker@Cyan]
			],
			
		],
		"PacletInfo.wl"
	],
	Spacer[20],Magnify["->",8],Spacer[20],
	Panel[
		FileTreeDiagram[
			PacletObject[File["~/Desktop/ConnorGray__MyPaclet"]]["Location"],
			(StringContainsQ[#,"MyPaclet.wl"])&,
			Magnification->2
		],
		"ConnorGray__MyPaclet directory"
	]
}]

Needs["ConnorGray`MyPaclet`"]

PacletDirectoryLoad[pacletDirectory]//Last

Needs["ConnorGray`MyPaclet`"]

FindFile["ConnorGray`MyPaclet`"]

Notes

The “Context” option extends the system via FindFile.

If your paclet has a PublisherID, that PublisherID must be used to prefix and contexts provided by your paclet. This is a requirement of the Wolfram Paclet Repository, and ensures that publishers have separate namespaces.

The “Context” option has two fundamental forms:

“Context” -> “SomeContext`”

Maps to a file based on the context name, e.g. SomeContext.wl.

“Context” -> { {“SomeContext`”, “SomeFile.wl”} ... }

Maps to the explicitly specified file name, e.g. “SomeFile.wl”

The first form is the most common.

“Documentation” extensions

Row[{
	Panel[
		Style[
			StringStyleReplace[
				ReadString[FileNameJoin[{pacletDirectory,"PacletInfo.wl"}]],
				t:RegularExpression["{[^{}]+\"Documentation\"[^}]+}"]:>Style[
					Framed[StringReplace[t,"\n                "->"\n"]],
					Darker@Cyan
				]
			],
			
		],
		"PacletInfo.wl"
	],
	Spacer[20],Magnify["->",8],Spacer[20],
	Panel[
		FileTreeDiagram[
			PacletObject[File["~/Desktop/ConnorGray__MyPaclet"]]["Location"],
			(StringContainsQ[#,"Documentation"])&,
			Magnification->2
		],
		"ConnorGray__MyPaclet directory"
	]
}]

Authoring Documentation

imageA=;
imageB=;Row[{Image[imageA,Magnification->1],Spacer[20],Magnify["->",5],Spacer[20],Image[imageB,Magnification->1]}]

DocumentationTools provides a palette for authoring Wolfram-style documentation for paclets.

The DocumentationTools palette can be opened by clicking on the Palettes > DocumentationTools menu item.

Adding a new symbol documentation page

Notes

The most common type of documentation pages are symbol reference pages.

The DocumentationTools palette provides tools for authoring symbol reference pages, guide pages, and tech note pages.

The ‘Authoring Paclet Documentation’ talk will cover the details of writing documentation in more detail.

https://wtc2021.pathable.co/meetings/virtual/TWZZfzDevDCGgLamg

The URI is used to identify a piece of documentation, and is used to locate the page in the Wolfram Documentation Center.

Each usage message should be a complete sentence, where the text describes what action is performed by each form of a function.

Names which stand in for arguments should be formatted using Template Input.

Building paclet documentation

SystemOpen[pacletDirectory]

PacletDocumentationBuild[pacletDirectory]

Building a single file

Needs["DocumentationBuild`"];

filter=Function[file,
	StringContainsQ[file,"SayHello.nb"]
];

DocumentationBuildNotebooks[
	FileNameJoin[{pacletDirectory,"Documentation"}],
	FileNameJoin[{pacletDirectory,"build","ConnorGray__MyPaclet","Documentation"}],
	filter
]

Notes

Historically, the way to build paclet documentation was using the Wolfram Workbench plugin for the Eclipse IDE.

Starting in version 13, the capability to build documentation is now built into the main system.

Building just your paclet’s documentation is convenient during development, when you want to be able to quickly see your changes.

Building the complete paclet

PacletBuild[pacletDirectory]

PacletInstall[FileNameJoin[{pacletDirectory,"build","ConnorGray__MyPaclet-0.0.1.paclet"}]]

Viewing our build documentation

Documentation for installed paclets can be viewed from the Wolfram Documentation Center by searching for the exact name of a page, or by typing in a relevant search term.

Note: Open the documentation in v12.3, due to bug in the v13 beta.

Publishing documentation to the Cloud

Deploying Notebook Documentation

PacletDocumentationBuild[
	pacletDirectory,
	CloudObject["MyPacletDocumentation",Permissions->"Public"]
]

Deploying HTML Documentation

PacletDocumentationBuild[
	pacletDirectory,
	CloudObject["HTMLMyPacletDocumentation",Permissions->"Public"],
	"HTML"
]

Success[]

The Wolfram Paclet Repository

https://resources.wolframcloud.com/PacletRepository

The ‘Paclets and the Wolfram Paclet Repository’ talk given by Todd Gayley and Bob Sandheinrich this morning explains in more detail what a Publisher ID is and how it relates to the Wolfram Paclet Repository.

https://wtc2021.pathable.co/meetings/virtual/pzbvjjMgah6wA5EDN

BarcodeImage["https://wtc2021.pathable.co/meetings/virtual/pzbvjjMgah6wA5EDN","QR"]