1
1
mirror of https://github.com/wader/fq.git synced 2024-12-25 22:34:14 +03:00

Merge pull request #422 from wader/markdown

Move format documentation to markdown again
This commit is contained in:
Mattias Wadman 2022-09-11 00:59:49 +02:00 committed by GitHub
commit 577ea7665c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 1771 additions and 633 deletions

1
.gitattributes vendored
View File

@ -3,3 +3,4 @@
*.json eol=lf *.json eol=lf
*.jq eol=lf *.jq eol=lf
*.xml eol=lf *.xml eol=lf
*.md eol=lf

View File

@ -48,7 +48,7 @@ avc_sps,
[avro_ocf](doc/formats.md#avro_ocf), [avro_ocf](doc/formats.md#avro_ocf),
[bencode](doc/formats.md#bencode), [bencode](doc/formats.md#bencode),
bitcoin_blkdat, bitcoin_blkdat,
bitcoin_block, [bitcoin_block](doc/formats.md#bitcoin_block),
bitcoin_script, bitcoin_script,
bitcoin_transaction, bitcoin_transaction,
bsd_loopback_frame, bsd_loopback_frame,
@ -91,6 +91,7 @@ json,
jsonl, jsonl,
[macho](doc/formats.md#macho), [macho](doc/formats.md#macho),
macho_fat, macho_fat,
markdown,
[matroska](doc/formats.md#matroska), [matroska](doc/formats.md#matroska),
[mp3](doc/formats.md#mp3), [mp3](doc/formats.md#mp3),
mp3_frame, mp3_frame,

View File

@ -2,14 +2,13 @@
def code: "`\(.)`"; def code: "`\(.)`";
def nbsp: gsub(" "; " "); def nbsp: gsub(" "; " ");
def has_section($f; $fhelp): $fhelp.notes or $fhelp.examples or $fhelp.links or $f.decode_in_arg; def has_section($f; $fhelp): $fhelp.notes or $fhelp.examples or $f.decode_in_arg or ((_registry.files[][] | select(.name=="\($f.name).md").data) // false);
def formats_list: def formats_list:
[ formats [ formats[] as $f
| to_entries[] as {$key, $value} | ({} | _help_format_enrich("fq"; $f; false)) as $fhelp
| (_format_func($key; "_help")? // {}) as $fhelp | if has_section($f; $fhelp) then "[\($f.name)](doc/formats.md#\($f.name))"
| if has_section($value; $fhelp) then "[\($key)](doc/formats.md#\($key))" else $f.name
else $key
end end
] | join(",\n"); ] | join(",\n");
@ -71,7 +70,8 @@ def formats_table:
def formats_sections: def formats_sections:
( formats[] as $f ( formats[] as $f
| (_format_func($f.name; "_help")? // {} | _help_format_enrich("fq"; $f; false)) as $fhelp | ((_registry.files[][] | select(.name=="\($f.name).md").data) // false) as $doc
| ({} | _help_format_enrich("fq"; $f; false)) as $fhelp
| select(has_section($f; $fhelp)) | select(has_section($f; $fhelp))
| "### \($f.name)" | "### \($f.name)"
, "" , ""
@ -134,16 +134,5 @@ def formats_sections:
) )
else empty else empty
end end
, if $fhelp.links then , ($doc // empty)
( "#### References and links"
, ""
, ( $fhelp.links[]
| if .title then "- [\(.title)](\(.url))"
else "- \(.url)"
end
)
, ""
)
else empty
end
); );

View File

@ -2,121 +2,122 @@
[fq -rn -L . 'include "formats"; formats_table']: sh-start [fq -rn -L . 'include "formats"; formats_table']: sh-start
|Name |Description |Dependencies| |Name |Description |Dependencies|
|- |- |-| |- |- |-|
|[`aac_frame`](#aac_frame) |Advanced&nbsp;Audio&nbsp;Coding&nbsp;frame |<sub></sub>| |[`aac_frame`](#aac_frame) |Advanced&nbsp;Audio&nbsp;Coding&nbsp;frame |<sub></sub>|
|`adts` |Audio&nbsp;Data&nbsp;Transport&nbsp;Stream |<sub>`adts_frame`</sub>| |`adts` |Audio&nbsp;Data&nbsp;Transport&nbsp;Stream |<sub>`adts_frame`</sub>|
|`adts_frame` |Audio&nbsp;Data&nbsp;Transport&nbsp;Stream&nbsp;frame |<sub>`aac_frame`</sub>| |`adts_frame` |Audio&nbsp;Data&nbsp;Transport&nbsp;Stream&nbsp;frame |<sub>`aac_frame`</sub>|
|`amf0` |Action&nbsp;Message&nbsp;Format&nbsp;0 |<sub></sub>| |`amf0` |Action&nbsp;Message&nbsp;Format&nbsp;0 |<sub></sub>|
|`apev2` |APEv2&nbsp;metadata&nbsp;tag |<sub>`image`</sub>| |`apev2` |APEv2&nbsp;metadata&nbsp;tag |<sub>`image`</sub>|
|`ar` |Unix&nbsp;archive |<sub>`probe`</sub>| |`ar` |Unix&nbsp;archive |<sub>`probe`</sub>|
|[`asn1_ber`](#asn1_ber) |ASN1&nbsp;BER&nbsp;(basic&nbsp;encoding&nbsp;rules,&nbsp;also&nbsp;CER&nbsp;and&nbsp;DER)|<sub></sub>| |[`asn1_ber`](#asn1_ber) |ASN1&nbsp;BER&nbsp;(basic&nbsp;encoding&nbsp;rules,&nbsp;also&nbsp;CER&nbsp;and&nbsp;DER)|<sub></sub>|
|`av1_ccr` |AV1&nbsp;Codec&nbsp;Configuration&nbsp;Record |<sub></sub>| |`av1_ccr` |AV1&nbsp;Codec&nbsp;Configuration&nbsp;Record |<sub></sub>|
|`av1_frame` |AV1&nbsp;frame |<sub>`av1_obu`</sub>| |`av1_frame` |AV1&nbsp;frame |<sub>`av1_obu`</sub>|
|`av1_obu` |AV1&nbsp;Open&nbsp;Bitstream&nbsp;Unit |<sub></sub>| |`av1_obu` |AV1&nbsp;Open&nbsp;Bitstream&nbsp;Unit |<sub></sub>|
|`avc_annexb` |H.264/AVC&nbsp;Annex&nbsp;B |<sub>`avc_nalu`</sub>| |`avc_annexb` |H.264/AVC&nbsp;Annex&nbsp;B |<sub>`avc_nalu`</sub>|
|[`avc_au`](#avc_au) |H.264/AVC&nbsp;Access&nbsp;Unit |<sub>`avc_nalu`</sub>| |[`avc_au`](#avc_au) |H.264/AVC&nbsp;Access&nbsp;Unit |<sub>`avc_nalu`</sub>|
|`avc_dcr` |H.264/AVC&nbsp;Decoder&nbsp;Configuration&nbsp;Record |<sub>`avc_nalu`</sub>| |`avc_dcr` |H.264/AVC&nbsp;Decoder&nbsp;Configuration&nbsp;Record |<sub>`avc_nalu`</sub>|
|`avc_nalu` |H.264/AVC&nbsp;Network&nbsp;Access&nbsp;Layer&nbsp;Unit |<sub>`avc_sps` `avc_pps` `avc_sei`</sub>| |`avc_nalu` |H.264/AVC&nbsp;Network&nbsp;Access&nbsp;Layer&nbsp;Unit |<sub>`avc_sps` `avc_pps` `avc_sei`</sub>|
|`avc_pps` |H.264/AVC&nbsp;Picture&nbsp;Parameter&nbsp;Set |<sub></sub>| |`avc_pps` |H.264/AVC&nbsp;Picture&nbsp;Parameter&nbsp;Set |<sub></sub>|
|`avc_sei` |H.264/AVC&nbsp;Supplemental&nbsp;Enhancement&nbsp;Information |<sub></sub>| |`avc_sei` |H.264/AVC&nbsp;Supplemental&nbsp;Enhancement&nbsp;Information |<sub></sub>|
|`avc_sps` |H.264/AVC&nbsp;Sequence&nbsp;Parameter&nbsp;Set |<sub></sub>| |`avc_sps` |H.264/AVC&nbsp;Sequence&nbsp;Parameter&nbsp;Set |<sub></sub>|
|[`avro_ocf`](#avro_ocf) |Avro&nbsp;object&nbsp;container&nbsp;file |<sub></sub>| |[`avro_ocf`](#avro_ocf) |Avro&nbsp;object&nbsp;container&nbsp;file |<sub></sub>|
|[`bencode`](#bencode) |BitTorrent&nbsp;bencoding |<sub></sub>| |[`bencode`](#bencode) |BitTorrent&nbsp;bencoding |<sub></sub>|
|`bitcoin_blkdat` |Bitcoin&nbsp;blk.dat |<sub>`bitcoin_block`</sub>| |`bitcoin_blkdat` |Bitcoin&nbsp;blk.dat |<sub>`bitcoin_block`</sub>|
|`bitcoin_block` |Bitcoin&nbsp;block |<sub>`bitcoin_transaction`</sub>| |[`bitcoin_block`](#bitcoin_block) |Bitcoin&nbsp;block |<sub>`bitcoin_transaction`</sub>|
|`bitcoin_script` |Bitcoin&nbsp;script |<sub></sub>| |`bitcoin_script` |Bitcoin&nbsp;script |<sub></sub>|
|`bitcoin_transaction` |Bitcoin&nbsp;transaction |<sub>`bitcoin_script`</sub>| |`bitcoin_transaction` |Bitcoin&nbsp;transaction |<sub>`bitcoin_script`</sub>|
|`bsd_loopback_frame` |BSD&nbsp;loopback&nbsp;frame |<sub>`inet_packet`</sub>| |`bsd_loopback_frame` |BSD&nbsp;loopback&nbsp;frame |<sub>`inet_packet`</sub>|
|[`bson`](#bson) |Binary&nbsp;JSON |<sub></sub>| |[`bson`](#bson) |Binary&nbsp;JSON |<sub></sub>|
|`bzip2` |bzip2&nbsp;compression |<sub>`probe`</sub>| |`bzip2` |bzip2&nbsp;compression |<sub>`probe`</sub>|
|[`cbor`](#cbor) |Concise&nbsp;Binary&nbsp;Object&nbsp;Representation |<sub></sub>| |[`cbor`](#cbor) |Concise&nbsp;Binary&nbsp;Object&nbsp;Representation |<sub></sub>|
|[`csv`](#csv) |Comma&nbsp;separated&nbsp;values |<sub></sub>| |[`csv`](#csv) |Comma&nbsp;separated&nbsp;values |<sub></sub>|
|`dns` |DNS&nbsp;packet |<sub></sub>| |`dns` |DNS&nbsp;packet |<sub></sub>|
|`dns_tcp` |DNS&nbsp;packet&nbsp;(TCP) |<sub></sub>| |`dns_tcp` |DNS&nbsp;packet&nbsp;(TCP) |<sub></sub>|
|`elf` |Executable&nbsp;and&nbsp;Linkable&nbsp;Format |<sub></sub>| |`elf` |Executable&nbsp;and&nbsp;Linkable&nbsp;Format |<sub></sub>|
|`ether8023_frame` |Ethernet&nbsp;802.3&nbsp;frame |<sub>`inet_packet`</sub>| |`ether8023_frame` |Ethernet&nbsp;802.3&nbsp;frame |<sub>`inet_packet`</sub>|
|`exif` |Exchangeable&nbsp;Image&nbsp;File&nbsp;Format |<sub></sub>| |`exif` |Exchangeable&nbsp;Image&nbsp;File&nbsp;Format |<sub></sub>|
|`fairplay_spc` |FairPlay&nbsp;Server&nbsp;Playback&nbsp;Context |<sub></sub>| |`fairplay_spc` |FairPlay&nbsp;Server&nbsp;Playback&nbsp;Context |<sub></sub>|
|`flac` |Free&nbsp;Lossless&nbsp;Audio&nbsp;Codec&nbsp;file |<sub>`flac_metadatablocks` `flac_frame`</sub>| |`flac` |Free&nbsp;Lossless&nbsp;Audio&nbsp;Codec&nbsp;file |<sub>`flac_metadatablocks` `flac_frame`</sub>|
|[`flac_frame`](#flac_frame) |FLAC&nbsp;frame |<sub></sub>| |[`flac_frame`](#flac_frame) |FLAC&nbsp;frame |<sub></sub>|
|`flac_metadatablock` |FLAC&nbsp;metadatablock |<sub>`flac_streaminfo` `flac_picture` `vorbis_comment`</sub>| |`flac_metadatablock` |FLAC&nbsp;metadatablock |<sub>`flac_streaminfo` `flac_picture` `vorbis_comment`</sub>|
|`flac_metadatablocks` |FLAC&nbsp;metadatablocks |<sub>`flac_metadatablock`</sub>| |`flac_metadatablocks` |FLAC&nbsp;metadatablocks |<sub>`flac_metadatablock`</sub>|
|`flac_picture` |FLAC&nbsp;metadatablock&nbsp;picture |<sub>`image`</sub>| |`flac_picture` |FLAC&nbsp;metadatablock&nbsp;picture |<sub>`image`</sub>|
|`flac_streaminfo` |FLAC&nbsp;streaminfo |<sub></sub>| |`flac_streaminfo` |FLAC&nbsp;streaminfo |<sub></sub>|
|`gif` |Graphics&nbsp;Interchange&nbsp;Format |<sub></sub>| |`gif` |Graphics&nbsp;Interchange&nbsp;Format |<sub></sub>|
|`gzip` |gzip&nbsp;compression |<sub>`probe`</sub>| |`gzip` |gzip&nbsp;compression |<sub>`probe`</sub>|
|`hevc_annexb` |H.265/HEVC&nbsp;Annex&nbsp;B |<sub>`hevc_nalu`</sub>| |`hevc_annexb` |H.265/HEVC&nbsp;Annex&nbsp;B |<sub>`hevc_nalu`</sub>|
|[`hevc_au`](#hevc_au) |H.265/HEVC&nbsp;Access&nbsp;Unit |<sub>`hevc_nalu`</sub>| |[`hevc_au`](#hevc_au) |H.265/HEVC&nbsp;Access&nbsp;Unit |<sub>`hevc_nalu`</sub>|
|`hevc_dcr` |H.265/HEVC&nbsp;Decoder&nbsp;Configuration&nbsp;Record |<sub>`hevc_nalu`</sub>| |`hevc_dcr` |H.265/HEVC&nbsp;Decoder&nbsp;Configuration&nbsp;Record |<sub>`hevc_nalu`</sub>|
|`hevc_nalu` |H.265/HEVC&nbsp;Network&nbsp;Access&nbsp;Layer&nbsp;Unit |<sub>`hevc_vps` `hevc_pps` `hevc_sps`</sub>| |`hevc_nalu` |H.265/HEVC&nbsp;Network&nbsp;Access&nbsp;Layer&nbsp;Unit |<sub>`hevc_vps` `hevc_pps` `hevc_sps`</sub>|
|`hevc_pps` |H.265/HEVC&nbsp;Picture&nbsp;Parameter&nbsp;Set |<sub></sub>| |`hevc_pps` |H.265/HEVC&nbsp;Picture&nbsp;Parameter&nbsp;Set |<sub></sub>|
|`hevc_sps` |H.265/HEVC&nbsp;Sequence&nbsp;Parameter&nbsp;Set |<sub></sub>| |`hevc_sps` |H.265/HEVC&nbsp;Sequence&nbsp;Parameter&nbsp;Set |<sub></sub>|
|`hevc_vps` |H.265/HEVC&nbsp;Video&nbsp;Parameter&nbsp;Set |<sub></sub>| |`hevc_vps` |H.265/HEVC&nbsp;Video&nbsp;Parameter&nbsp;Set |<sub></sub>|
|[`html`](#html) |HyperText&nbsp;Markup&nbsp;Language |<sub></sub>| |[`html`](#html) |HyperText&nbsp;Markup&nbsp;Language |<sub></sub>|
|`icc_profile` |International&nbsp;Color&nbsp;Consortium&nbsp;profile |<sub></sub>| |`icc_profile` |International&nbsp;Color&nbsp;Consortium&nbsp;profile |<sub></sub>|
|`icmp` |Internet&nbsp;Control&nbsp;Message&nbsp;Protocol |<sub></sub>| |`icmp` |Internet&nbsp;Control&nbsp;Message&nbsp;Protocol |<sub></sub>|
|`icmpv6` |Internet&nbsp;Control&nbsp;Message&nbsp;Protocol&nbsp;v6 |<sub></sub>| |`icmpv6` |Internet&nbsp;Control&nbsp;Message&nbsp;Protocol&nbsp;v6 |<sub></sub>|
|`id3v1` |ID3v1&nbsp;metadata |<sub></sub>| |`id3v1` |ID3v1&nbsp;metadata |<sub></sub>|
|`id3v11` |ID3v1.1&nbsp;metadata |<sub></sub>| |`id3v11` |ID3v1.1&nbsp;metadata |<sub></sub>|
|`id3v2` |ID3v2&nbsp;metadata |<sub>`image`</sub>| |`id3v2` |ID3v2&nbsp;metadata |<sub>`image`</sub>|
|`ipv4_packet` |Internet&nbsp;protocol&nbsp;v4&nbsp;packet |<sub>`ip_packet`</sub>| |`ipv4_packet` |Internet&nbsp;protocol&nbsp;v4&nbsp;packet |<sub>`ip_packet`</sub>|
|`ipv6_packet` |Internet&nbsp;protocol&nbsp;v6&nbsp;packet |<sub>`ip_packet`</sub>| |`ipv6_packet` |Internet&nbsp;protocol&nbsp;v6&nbsp;packet |<sub>`ip_packet`</sub>|
|`jpeg` |Joint&nbsp;Photographic&nbsp;Experts&nbsp;Group&nbsp;file |<sub>`exif` `icc_profile`</sub>| |`jpeg` |Joint&nbsp;Photographic&nbsp;Experts&nbsp;Group&nbsp;file |<sub>`exif` `icc_profile`</sub>|
|`json` |JavaScript&nbsp;Object&nbsp;Notation |<sub></sub>| |`json` |JavaScript&nbsp;Object&nbsp;Notation |<sub></sub>|
|`jsonl` |JavaScript&nbsp;Object&nbsp;Notation&nbsp;Lines |<sub></sub>| |`jsonl` |JavaScript&nbsp;Object&nbsp;Notation&nbsp;Lines |<sub></sub>|
|[`macho`](#macho) |Mach-O&nbsp;macOS&nbsp;executable |<sub></sub>| |[`macho`](#macho) |Mach-O&nbsp;macOS&nbsp;executable |<sub></sub>|
|`macho_fat` |Fat&nbsp;Mach-O&nbsp;macOS&nbsp;executable&nbsp;(multi-architecture) |<sub>`macho`</sub>| |`macho_fat` |Fat&nbsp;Mach-O&nbsp;macOS&nbsp;executable&nbsp;(multi-architecture) |<sub>`macho`</sub>|
|[`matroska`](#matroska) |Matroska&nbsp;file |<sub>`aac_frame` `av1_ccr` `av1_frame` `avc_au` `avc_dcr` `flac_frame` `flac_metadatablocks` `hevc_au` `hevc_dcr` `image` `mp3_frame` `mpeg_asc` `mpeg_pes_packet` `mpeg_spu` `opus_packet` `vorbis_packet` `vp8_frame` `vp9_cfm` `vp9_frame`</sub>| |`markdown` |Markdown |<sub></sub>|
|[`mp3`](#mp3) |MP3&nbsp;file |<sub>`id3v2` `id3v1` `id3v11` `apev2` `mp3_frame`</sub>| |[`matroska`](#matroska) |Matroska&nbsp;file |<sub>`aac_frame` `av1_ccr` `av1_frame` `avc_au` `avc_dcr` `flac_frame` `flac_metadatablocks` `hevc_au` `hevc_dcr` `image` `mp3_frame` `mpeg_asc` `mpeg_pes_packet` `mpeg_spu` `opus_packet` `vorbis_packet` `vp8_frame` `vp9_cfm` `vp9_frame`</sub>|
|`mp3_frame` |MPEG&nbsp;audio&nbsp;layer&nbsp;3&nbsp;frame |<sub>`xing`</sub>| |[`mp3`](#mp3) |MP3&nbsp;file |<sub>`id3v2` `id3v1` `id3v11` `apev2` `mp3_frame`</sub>|
|[`mp4`](#mp4) |ISOBMFF&nbsp;MPEG-4&nbsp;part&nbsp;12&nbsp;and&nbsp;similar |<sub>`aac_frame` `av1_ccr` `av1_frame` `avc_au` `avc_dcr` `flac_frame` `flac_metadatablocks` `hevc_au` `hevc_dcr` `icc_profile` `id3v2` `image` `jpeg` `mp3_frame` `mpeg_es` `mpeg_pes_packet` `opus_packet` `prores_frame` `protobuf_widevine` `pssh_playready` `vorbis_packet` `vp9_frame` `vpx_ccr`</sub>| |`mp3_frame` |MPEG&nbsp;audio&nbsp;layer&nbsp;3&nbsp;frame |<sub>`xing`</sub>|
|`mpeg_asc` |MPEG-4&nbsp;Audio&nbsp;Specific&nbsp;Config |<sub></sub>| |[`mp4`](#mp4) |ISOBMFF,&nbsp;QuickTime&nbsp;and&nbsp;similar |<sub>`aac_frame` `av1_ccr` `av1_frame` `avc_au` `avc_dcr` `flac_frame` `flac_metadatablocks` `hevc_au` `hevc_dcr` `icc_profile` `id3v2` `image` `jpeg` `mp3_frame` `mpeg_es` `mpeg_pes_packet` `opus_packet` `prores_frame` `protobuf_widevine` `pssh_playready` `vorbis_packet` `vp9_frame` `vpx_ccr`</sub>|
|`mpeg_es` |MPEG&nbsp;Elementary&nbsp;Stream |<sub>`mpeg_asc` `vorbis_packet`</sub>| |`mpeg_asc` |MPEG-4&nbsp;Audio&nbsp;Specific&nbsp;Config |<sub></sub>|
|`mpeg_pes` |MPEG&nbsp;Packetized&nbsp;elementary&nbsp;stream |<sub>`mpeg_pes_packet` `mpeg_spu`</sub>| |`mpeg_es` |MPEG&nbsp;Elementary&nbsp;Stream |<sub>`mpeg_asc` `vorbis_packet`</sub>|
|`mpeg_pes_packet` |MPEG&nbsp;Packetized&nbsp;elementary&nbsp;stream&nbsp;packet |<sub></sub>| |`mpeg_pes` |MPEG&nbsp;Packetized&nbsp;elementary&nbsp;stream |<sub>`mpeg_pes_packet` `mpeg_spu`</sub>|
|`mpeg_spu` |Sub&nbsp;Picture&nbsp;Unit&nbsp;(DVD&nbsp;subtitle) |<sub></sub>| |`mpeg_pes_packet` |MPEG&nbsp;Packetized&nbsp;elementary&nbsp;stream&nbsp;packet |<sub></sub>|
|`mpeg_ts` |MPEG&nbsp;Transport&nbsp;Stream |<sub></sub>| |`mpeg_spu` |Sub&nbsp;Picture&nbsp;Unit&nbsp;(DVD&nbsp;subtitle) |<sub></sub>|
|[`msgpack`](#msgpack) |MessagePack |<sub></sub>| |`mpeg_ts` |MPEG&nbsp;Transport&nbsp;Stream |<sub></sub>|
|`ogg` |OGG&nbsp;file |<sub>`ogg_page` `vorbis_packet` `opus_packet` `flac_metadatablock` `flac_frame`</sub>| |[`msgpack`](#msgpack) |MessagePack |<sub></sub>|
|`ogg_page` |OGG&nbsp;page |<sub></sub>| |`ogg` |OGG&nbsp;file |<sub>`ogg_page` `vorbis_packet` `opus_packet` `flac_metadatablock` `flac_frame`</sub>|
|`opus_packet` |Opus&nbsp;packet |<sub>`vorbis_comment`</sub>| |`ogg_page` |OGG&nbsp;page |<sub></sub>|
|`pcap` |PCAP&nbsp;packet&nbsp;capture |<sub>`link_frame` `tcp_stream` `ipv4_packet`</sub>| |`opus_packet` |Opus&nbsp;packet |<sub>`vorbis_comment`</sub>|
|`pcapng` |PCAPNG&nbsp;packet&nbsp;capture |<sub>`link_frame` `tcp_stream` `ipv4_packet`</sub>| |`pcap` |PCAP&nbsp;packet&nbsp;capture |<sub>`link_frame` `tcp_stream` `ipv4_packet`</sub>|
|`png` |Portable&nbsp;Network&nbsp;Graphics&nbsp;file |<sub>`icc_profile` `exif`</sub>| |`pcapng` |PCAPNG&nbsp;packet&nbsp;capture |<sub>`link_frame` `tcp_stream` `ipv4_packet`</sub>|
|`prores_frame` |Apple&nbsp;ProRes&nbsp;frame |<sub></sub>| |`png` |Portable&nbsp;Network&nbsp;Graphics&nbsp;file |<sub>`icc_profile` `exif`</sub>|
|[`protobuf`](#protobuf) |Protobuf |<sub></sub>| |`prores_frame` |Apple&nbsp;ProRes&nbsp;frame |<sub></sub>|
|`protobuf_widevine` |Widevine&nbsp;protobuf |<sub>`protobuf`</sub>| |[`protobuf`](#protobuf) |Protobuf |<sub></sub>|
|`pssh_playready` |PlayReady&nbsp;PSSH |<sub></sub>| |`protobuf_widevine` |Widevine&nbsp;protobuf |<sub>`protobuf`</sub>|
|`raw` |Raw&nbsp;bits |<sub></sub>| |`pssh_playready` |PlayReady&nbsp;PSSH |<sub></sub>|
|[`rtmp`](#rtmp) |Real-Time&nbsp;Messaging&nbsp;Protocol |<sub>`amf0` `mpeg_asc`</sub>| |`raw` |Raw&nbsp;bits |<sub></sub>|
|`sll2_packet` |Linux&nbsp;cooked&nbsp;capture&nbsp;encapsulation&nbsp;v2 |<sub>`inet_packet`</sub>| |[`rtmp`](#rtmp) |Real-Time&nbsp;Messaging&nbsp;Protocol |<sub>`amf0` `mpeg_asc`</sub>|
|`sll_packet` |Linux&nbsp;cooked&nbsp;capture&nbsp;encapsulation |<sub>`inet_packet`</sub>| |`sll2_packet` |Linux&nbsp;cooked&nbsp;capture&nbsp;encapsulation&nbsp;v2 |<sub>`inet_packet`</sub>|
|`tar` |Tar&nbsp;archive |<sub>`probe`</sub>| |`sll_packet` |Linux&nbsp;cooked&nbsp;capture&nbsp;encapsulation |<sub>`inet_packet`</sub>|
|`tcp_segment` |Transmission&nbsp;control&nbsp;protocol&nbsp;segment |<sub></sub>| |`tar` |Tar&nbsp;archive |<sub>`probe`</sub>|
|`tiff` |Tag&nbsp;Image&nbsp;File&nbsp;Format |<sub>`icc_profile`</sub>| |`tcp_segment` |Transmission&nbsp;control&nbsp;protocol&nbsp;segment |<sub></sub>|
|`toml` |Tom's&nbsp;Obvious,&nbsp;Minimal&nbsp;Language |<sub></sub>| |`tiff` |Tag&nbsp;Image&nbsp;File&nbsp;Format |<sub>`icc_profile`</sub>|
|`udp_datagram` |User&nbsp;datagram&nbsp;protocol |<sub>`udp_payload`</sub>| |`toml` |Tom's&nbsp;Obvious,&nbsp;Minimal&nbsp;Language |<sub></sub>|
|`vorbis_comment` |Vorbis&nbsp;comment |<sub>`flac_picture`</sub>| |`udp_datagram` |User&nbsp;datagram&nbsp;protocol |<sub>`udp_payload`</sub>|
|`vorbis_packet` |Vorbis&nbsp;packet |<sub>`vorbis_comment`</sub>| |`vorbis_comment` |Vorbis&nbsp;comment |<sub>`flac_picture`</sub>|
|`vp8_frame` |VP8&nbsp;frame |<sub></sub>| |`vorbis_packet` |Vorbis&nbsp;packet |<sub>`vorbis_comment`</sub>|
|`vp9_cfm` |VP9&nbsp;Codec&nbsp;Feature&nbsp;Metadata |<sub></sub>| |`vp8_frame` |VP8&nbsp;frame |<sub></sub>|
|`vp9_frame` |VP9&nbsp;frame |<sub></sub>| |`vp9_cfm` |VP9&nbsp;Codec&nbsp;Feature&nbsp;Metadata |<sub></sub>|
|`vpx_ccr` |VPX&nbsp;Codec&nbsp;Configuration&nbsp;Record |<sub></sub>| |`vp9_frame` |VP9&nbsp;frame |<sub></sub>|
|`wasm` |WebAssembly&nbsp;Binary&nbsp;Format |<sub></sub>| |`vpx_ccr` |VPX&nbsp;Codec&nbsp;Configuration&nbsp;Record |<sub></sub>|
|`wav` |WAV&nbsp;file |<sub>`id3v2` `id3v1` `id3v11`</sub>| |`wasm` |WebAssembly&nbsp;Binary&nbsp;Format |<sub></sub>|
|`webp` |WebP&nbsp;image |<sub>`vp8_frame`</sub>| |`wav` |WAV&nbsp;file |<sub>`id3v2` `id3v1` `id3v11`</sub>|
|`xing` |Xing&nbsp;header |<sub></sub>| |`webp` |WebP&nbsp;image |<sub>`vp8_frame`</sub>|
|[`xml`](#xml) |Extensible&nbsp;Markup&nbsp;Language |<sub></sub>| |`xing` |Xing&nbsp;header |<sub></sub>|
|`yaml` |YAML&nbsp;Ain't&nbsp;Markup&nbsp;Language |<sub></sub>| |[`xml`](#xml) |Extensible&nbsp;Markup&nbsp;Language |<sub></sub>|
|[`zip`](#zip) |ZIP&nbsp;archive |<sub>`probe`</sub>| |`yaml` |YAML&nbsp;Ain't&nbsp;Markup&nbsp;Language |<sub></sub>|
|`image` |Group |<sub>`gif` `jpeg` `mp4` `png` `tiff` `webp`</sub>| |[`zip`](#zip) |ZIP&nbsp;archive |<sub>`probe`</sub>|
|`inet_packet` |Group |<sub>`ipv4_packet` `ipv6_packet`</sub>| |`image` |Group |<sub>`gif` `jpeg` `mp4` `png` `tiff` `webp`</sub>|
|`ip_packet` |Group |<sub>`icmp` `icmpv6` `tcp_segment` `udp_datagram`</sub>| |`inet_packet` |Group |<sub>`ipv4_packet` `ipv6_packet`</sub>|
|`link_frame` |Group |<sub>`bsd_loopback_frame` `ether8023_frame` `sll2_packet` `sll_packet`</sub>| |`ip_packet` |Group |<sub>`icmp` `icmpv6` `tcp_segment` `udp_datagram`</sub>|
|`probe` |Group |<sub>`adts` `ar` `avro_ocf` `bitcoin_blkdat` `bzip2` `elf` `flac` `gif` `gzip` `jpeg` `json` `jsonl` `macho` `macho_fat` `matroska` `mp3` `mp4` `mpeg_ts` `ogg` `pcap` `pcapng` `png` `tar` `tiff` `toml` `wasm` `wav` `webp` `xml` `yaml` `zip`</sub>| |`link_frame` |Group |<sub>`bsd_loopback_frame` `ether8023_frame` `sll2_packet` `sll_packet`</sub>|
|`tcp_stream` |Group |<sub>`dns_tcp` `rtmp`</sub>| |`probe` |Group |<sub>`adts` `ar` `avro_ocf` `bitcoin_blkdat` `bzip2` `elf` `flac` `gif` `gzip` `jpeg` `json` `jsonl` `macho` `macho_fat` `matroska` `mp3` `mp4` `mpeg_ts` `ogg` `pcap` `pcapng` `png` `tar` `tiff` `toml` `wasm` `wav` `webp` `xml` `yaml` `zip`</sub>|
|`udp_payload` |Group |<sub>`dns`</sub>| |`tcp_stream` |Group |<sub>`dns_tcp` `rtmp`</sub>|
|`udp_payload` |Group |<sub>`dns`</sub>|
[#]: sh-end [#]: sh-end
@ -161,35 +162,25 @@ Supports decoding BER, CER and DER (X.690).
- Does not support specifying a schema. - Does not support specifying a schema.
- Supports `torepr` but without schema all sequences and sets will be arrays. - Supports `torepr` but without schema all sequences and sets will be arrays.
#### Examples #### `frompem` can be used to decode certificates etc
`frompem` and `topem` can be used to work with PEM format ```sh
```
$ fq -d raw 'frompem | asn1_ber | d' cert.pem $ fq -d raw 'frompem | asn1_ber | d' cert.pem
``` ```
Can be used to decode nested parts #### Can decode nested values
```
```sh
$ fq -d asn1_ber '.constructed[1].value | asn1_ber' file.ber $ fq -d asn1_ber '.constructed[1].value | asn1_ber' file.ber
``` ```
If schema is known and not complicated it can be reproduced #### Manual schema
```
```sh
$ fq -d asn1_ber 'torepr as $r | ["version", "modulus", "private_exponent", "private_exponen", "prime1", "prime2", "exponent1", "exponent2", "coefficient"] | with_entries({key: .value, value: $r[.key]})' pkcs1.der $ fq -d asn1_ber 'torepr as $r | ["version", "modulus", "private_exponent", "private_exponen", "prime1", "prime2", "exponent1", "exponent2", "coefficient"] | with_entries({key: .value, value: $r[.key]})' pkcs1.der
``` ```
Supports `torepr` #### References
```
$ fq -d asn1_ber torepr file
```
Supports `torepr`
```
... | asn1_ber | torepr
```
#### References and links
- https://www.itu.int/ITU-T/studygroups/com10/languages/X.690_1297.pdf - https://www.itu.int/ITU-T/studygroups/com10/languages/X.690_1297.pdf
- https://en.wikipedia.org/wiki/X.690 - https://en.wikipedia.org/wiki/X.690
- https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/ - https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/
@ -222,70 +213,70 @@ Supports reading Avro Object Container Format (OCF) files based on the 1.11.0 sp
Capable of handling null, deflate, and snappy codecs for data compression. Capable of handling null, deflate, and snappy codecs for data compression.
Limitations: Limitations:
- Schema does not support self-referential types, only built-in types.
- Decimal logical types are not supported for decoding, will just be treated as their primitive type
#### References and links - Schema does not support self-referential types, only built-in types.
- Decimal logical types are not supported for decoding, will just be treated as their primitive type
#### References
- https://avro.apache.org/docs/current/spec.html#Object+Container+Files - https://avro.apache.org/docs/current/spec.html#Object+Container+Files
### bencode ### bencode
#### Convert represented value to JSON
```
$ fq -d bencode torepr file.torrent
```
#### References
- https://wiki.theory.org/BitTorrentSpecification#Bencoding
### bitcoin_block
#### Options
|Name |Default|Description|
|- |- |-|
|`has_header`|false |Has blkdat header|
#### Examples #### Examples
Supports `torepr` Decode file using bitcoin_block options
``` ```
$ fq -d bencode torepr file $ fq -d bitcoin_block -o has_header=false . file
``` ```
Supports `torepr` Decode value as bitcoin_block
``` ```
... | bencode | torepr ... | bitcoin_block({has_header:false})
``` ```
#### References and links
- https://wiki.theory.org/BitTorrentSpecification#Bencoding
### bson ### bson
#### Examples #### Convert represented value to JSON
BSON as JSON
``` ```
$ fq -d bson torepr file $ fq -d bson torepr file.bson
``` ```
Supports `torepr` ### Filter represented value
``` ```
$ fq -d bson torepr file $ fq -d bson 'torepr | select(.name=="bob")' file.bson
``` ```
Supports `torepr` #### References
``` - https://bsonspec.org/spec.html
... | bson | torepr
```
#### References and links
- https://wiki.theory.org/BitTorrentSpecification#Bencoding
### cbor ### cbor
#### Examples #### Convert represented value to JSON
Supports `torepr`
``` ```
$ fq -d cbor torepr file $ fq -d cbor torepr file.cbor
``` ```
Supports `torepr` #### References
```
... | cbor | torepr
```
#### References and links
- https://en.wikipedia.org/wiki/CBOR - https://en.wikipedia.org/wiki/CBOR
- https://www.rfc-editor.org/rfc/rfc8949.html - https://www.rfc-editor.org/rfc/rfc8949.html
@ -376,33 +367,30 @@ Decode value as html
Supports decoding vanilla and FAT Mach-O binaries. Supports decoding vanilla and FAT Mach-O binaries.
#### Examples #### Select 64bit load segments
Select 64bit load segments ```sh
```
$ fq '.load_commands[] | select(.cmd=="segment_64")' file $ fq '.load_commands[] | select(.cmd=="segment_64")' file
``` ```
#### References and links #### References
- https://github.com/aidansteele/osx-abi-macho-file-format-reference - https://github.com/aidansteele/osx-abi-macho-file-format-reference
### matroska ### matroska
#### Examples #### Lookup element path using `matroska_path`
Lookup element decode value using `matroska_path` ```sh
``` $ fq 'matroska_path(".Segment.Tracks[0)")' file.mkv
... | matroska_path(".Segment.Tracks[0)"
``` ```
Return `matroska_path` string for a box decode value #### Get element path using `matroska_path`
```
... | grep_by(.id == "Tracks") | matroska_path ```sh
$ fq 'grep_by(.id == "Tracks") | matroska_path' file.mkv
``` ```
#### References and links #### References
- https://tools.ietf.org/html/draft-ietf-cellar-ebml-00 - https://tools.ietf.org/html/draft-ietf-cellar-ebml-00
- https://matroska.org/technical/specs/index.html - https://matroska.org/technical/specs/index.html
- https://www.matroska.org/technical/basics.html - https://www.matroska.org/technical/basics.html
@ -432,8 +420,6 @@ Decode value as mp3
### mp4 ### mp4
Support `mp4_path`
#### Options #### Options
|Name |Default|Description| |Name |Default|Description|
@ -443,16 +429,6 @@ Support `mp4_path`
#### Examples #### Examples
Lookup box decode value using `mp4_path`
```
... | mp4_path(".moov.trak[1]")
```
Return `mp4_path` string for a box decode value
```
... | grep_by(.type == "trak") | mp4_path
```
Decode file using mp4 options Decode file using mp4 options
``` ```
$ fq -d mp4 -o allow_truncated=false -o decode_samples=true . file $ fq -d mp4 -o allow_truncated=false -o decode_samples=true . file
@ -463,48 +439,70 @@ Decode value as mp4
... | mp4({allow_truncated:false,decode_samples:true}) ... | mp4({allow_truncated:false,decode_samples:true})
``` ```
#### References and links #### `mp4_path($path)` - Lookup mp4 box using a mp4 box path.
```sh
# <decode value box> | mp4_path($path) -> <decode value box>
$ fq 'mp4_path(".moov.trak[1]")' file.mp4
```
#### `mp4_path` - Return mp4 box path for a decode value box.
```sh
# <decode value box> | mp4_path -> string
$ fq 'grep_by(.type == "trak") | mp4_path' file.mp4
```
#### Force decode a single box
```sh
$ fq -n '"AAAAHGVsc3QAAAAAAAAAAQAAADIAAAQAAAEAAA==" | frombase64 | mp4({force:true}) | d'
```
#### Don't decode samples and manually decode first sample for first track as a `aac_frame`
```sh
$ fq -o decode_samples=false '.tracks[0].samples[0] | aac_frame | d' file.mp4
```
#### Entries for first edit list as values
```sh
$ fq 'first(grep_by(.type=="elst").entries) | tovalue' file.mp4
```
#### References
- [ISO/IEC base media file format (MPEG-4 Part 12)](https://en.wikipedia.org/wiki/ISO/IEC_base_media_file_format) - [ISO/IEC base media file format (MPEG-4 Part 12)](https://en.wikipedia.org/wiki/ISO/IEC_base_media_file_format)
- [Quicktime file format](https://developer.apple.com/standards/qtff-2001.pdf) - [Quicktime file format](https://developer.apple.com/standards/qtff-2001.pdf)
### msgpack ### msgpack
#### Examples #### Convert represented value to JSON
Supports `torepr`
``` ```
$ fq -d msgpack torepr file $ fq -d msgpack torepr file.msgpack
``` ```
Supports `torepr` #### References
```
... | msgpack | torepr
```
#### References and links
- https://github.com/msgpack/msgpack/blob/master/spec.md - https://github.com/msgpack/msgpack/blob/master/spec.md
### protobuf ### protobuf
#### Examples #### Can decode sub messages
Can be used to decode sub messages ```sh
``` $ fq -d protobuf '.fields[6].wire_value | protobuf | d' file
$ fq -d protobuf '.fields[6].wire_value | protobuf | d'
``` ```
#### References and links #### References
- https://developers.google.com/protocol-buffers/docs/encoding - https://developers.google.com/protocol-buffers/docs/encoding
### rtmp ### rtmp
Current only supports plain RTMP (not RTMPT or encrypted variants etc) with AMF0 (not AMF3). Current only supports plain RTMP (not RTMPT or encrypted variants etc) with AMF0 (not AMF3).
#### References and links #### References
- https://rtmp.veriskope.com/docs/spec/ - https://rtmp.veriskope.com/docs/spec/
- https://rtmp.veriskope.com/pdf/video_file_format_spec_v10.pdf - https://rtmp.veriskope.com/pdf/video_file_format_spec_v10.pdf
@ -530,14 +528,11 @@ Decode value as xml
... | xml({array:false,attribute_prefix:"@",seq:false}) ... | xml({array:false,attribute_prefix:"@",seq:false})
``` ```
#### References and links #### References
- [xml.com's Converting Between XML and JSON](https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html) - [xml.com's Converting Between XML and JSON](https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html)
### zip ### zip
Supports ZIP64.
#### Options #### Options
|Name |Default|Description| |Name |Default|Description|
@ -556,9 +551,11 @@ Decode value as zip
... | zip({uncompress:true}) ... | zip({uncompress:true})
``` ```
#### References and links Supports ZIP64.
#### References
- https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT - https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
- https://opensource.apple.com/source/zip/zip-6/unzip/unzip/proginfo/extra.fld
[#]: sh-end [#]: sh-end

View File

@ -1919,17 +1919,23 @@
<polygon fill="paleturquoise" stroke="transparent" points="3858.81,-2025.5 3858.81,-2051.5 3899.81,-2051.5 3899.81,-2025.5 3858.81,-2025.5"/> <polygon fill="paleturquoise" stroke="transparent" points="3858.81,-2025.5 3858.81,-2051.5 3899.81,-2051.5 3899.81,-2025.5 3858.81,-2025.5"/>
<text text-anchor="start" x="3861.31" y="-2033.5" font-family="Times,serif" font-size="20.00">html</text> <text text-anchor="start" x="3861.31" y="-2033.5" font-family="Times,serif" font-size="20.00">html</text>
</g> </g>
<!-- msgpack --> <!-- markdown -->
<g id="node112" class="node"> <g id="node112" class="node">
<title>markdown</title>
<polygon fill="paleturquoise" stroke="transparent" points="3929.81,-2025.5 3929.81,-2051.5 4018.81,-2051.5 4018.81,-2025.5 3929.81,-2025.5"/>
<text text-anchor="start" x="3932.31" y="-2033.5" font-family="Times,serif" font-size="20.00">markdown</text>
</g>
<!-- msgpack -->
<g id="node113" class="node">
<title>msgpack</title> <title>msgpack</title>
<polygon fill="paleturquoise" stroke="transparent" points="3929.81,-2025.5 3929.81,-2051.5 4004.81,-2051.5 4004.81,-2025.5 3929.81,-2025.5"/> <polygon fill="paleturquoise" stroke="transparent" points="4048.81,-2025.5 4048.81,-2051.5 4123.81,-2051.5 4123.81,-2025.5 4048.81,-2025.5"/>
<text text-anchor="start" x="3932.31" y="-2033.5" font-family="Times,serif" font-size="20.00">msgpack</text> <text text-anchor="start" x="4051.31" y="-2033.5" font-family="Times,serif" font-size="20.00">msgpack</text>
</g> </g>
<!-- raw --> <!-- raw -->
<g id="node113" class="node"> <g id="node114" class="node">
<title>raw</title> <title>raw</title>
<polygon fill="paleturquoise" stroke="transparent" points="4036.81,-2025.5 4036.81,-2051.5 4071.81,-2051.5 4071.81,-2025.5 4036.81,-2025.5"/> <polygon fill="paleturquoise" stroke="transparent" points="4155.81,-2025.5 4155.81,-2051.5 4190.81,-2051.5 4190.81,-2025.5 4155.81,-2025.5"/>
<text text-anchor="start" x="4039.31" y="-2033.5" font-family="Times,serif" font-size="20.00">raw</text> <text text-anchor="start" x="4158.31" y="-2033.5" font-family="Times,serif" font-size="20.00">raw</text>
</g> </g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View File

@ -28,6 +28,7 @@ import (
_ "github.com/wader/fq/format/jpeg" _ "github.com/wader/fq/format/jpeg"
_ "github.com/wader/fq/format/json" _ "github.com/wader/fq/format/json"
_ "github.com/wader/fq/format/macho" _ "github.com/wader/fq/format/macho"
_ "github.com/wader/fq/format/markdown"
_ "github.com/wader/fq/format/math" _ "github.com/wader/fq/format/math"
_ "github.com/wader/fq/format/matroska" _ "github.com/wader/fq/format/matroska"
_ "github.com/wader/fq/format/mp3" _ "github.com/wader/fq/format/mp3"

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@ import (
) )
//go:embed asn1_ber.jq //go:embed asn1_ber.jq
//go:embed asn1_ber.md
var asn1FS embed.FS var asn1FS embed.FS
func init() { func init() {
@ -36,7 +37,7 @@ func init() {
Name: format.ASN1_BER, Name: format.ASN1_BER,
Description: "ASN1 BER (basic encoding rules, also CER and DER)", Description: "ASN1 BER (basic encoding rules, also CER and DER)",
DecodeFn: decodeASN1BER, DecodeFn: decodeASN1BER,
Functions: []string{"torepr", "_help"}, Functions: []string{"torepr"},
}) })
interp.RegisterFS(asn1FS) interp.RegisterFS(asn1FS)
} }

View File

@ -6,24 +6,3 @@ def _asn1_ber_torepr:
end end
else .constructed | map(_asn1_ber_torepr) else .constructed | map(_asn1_ber_torepr)
end; end;
def _asn1_ber__help:
{ notes: "Supports decoding BER, CER and DER (X.690).
- Currently no extra validation is done for CER and DER.
- Does not support specifying a schema.
- Supports `torepr` but without schema all sequences and sets will be arrays.",
examples: [
{comment: "`frompem` and `topem` can be used to work with PEM format", shell: "fq -d raw 'frompem | asn1_ber | d' cert.pem"},
{comment: "Can be used to decode nested parts", shell: "fq -d asn1_ber '.constructed[1].value | asn1_ber' file.ber"},
{ comment: "If schema is known and not complicated it can be reproduced",
shell: "fq -d asn1_ber 'torepr as $r | [\"version\", \"modulus\", \"private_exponent\", \"private_exponen\", \"prime1\", \"prime2\", \"exponent1\", \"exponent2\", \"coefficient\"] | with_entries({key: .value, value: $r[.key]})' pkcs1.der"
}
],
links: [
{url: "https://www.itu.int/ITU-T/studygroups/com10/languages/X.690_1297.pdf"},
{url: "https://en.wikipedia.org/wiki/X.690"},
{url: "https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/"},
{url: "https://lapo.it/asn1js/"}
]
};

29
format/asn1/asn1_ber.md Normal file
View File

@ -0,0 +1,29 @@
Supports decoding BER, CER and DER (X.690).
- Currently no extra validation is done for CER and DER.
- Does not support specifying a schema.
- Supports `torepr` but without schema all sequences and sets will be arrays.
#### `frompem` can be used to decode certificates etc
```sh
$ fq -d raw 'frompem | asn1_ber | d' cert.pem
```
#### Can decode nested values
```sh
$ fq -d asn1_ber '.constructed[1].value | asn1_ber' file.ber
```
#### Manual schema
```sh
$ fq -d asn1_ber 'torepr as $r | ["version", "modulus", "private_exponent", "private_exponen", "prime1", "prime2", "exponent1", "exponent2", "coefficient"] | with_entries({key: .value, value: $r[.key]})' pkcs1.der
```
#### References
- https://www.itu.int/ITU-T/studygroups/com10/languages/X.690_1297.pdf
- https://en.wikipedia.org/wiki/X.690
- https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/
- https://lapo.it/asn1js/

View File

@ -16,7 +16,7 @@ import (
"github.com/wader/fq/pkg/scalar" "github.com/wader/fq/pkg/scalar"
) )
//go:embed avro_ocf.jq //go:embed avro_ocf.md
var avroOcfFS embed.FS var avroOcfFS embed.FS
func init() { func init() {
@ -25,7 +25,6 @@ func init() {
Description: "Avro object container file", Description: "Avro object container file",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},
DecodeFn: decodeAvroOCF, DecodeFn: decodeAvroOCF,
Functions: []string{"_help"},
}) })
interp.RegisterFS(avroOcfFS) interp.RegisterFS(avroOcfFS)
} }

View File

@ -1,12 +0,0 @@
def _avro_ocf__help:
{ notes: "Supports reading Avro Object Container Format (OCF) files based on the 1.11.0 specification.
Capable of handling null, deflate, and snappy codecs for data compression.
Limitations:
- Schema does not support self-referential types, only built-in types.
- Decimal logical types are not supported for decoding, will just be treated as their primitive type",
links: [
{url: "https://avro.apache.org/docs/current/spec.html#Object+Container+Files"}
]
};

11
format/avro/avro_ocf.md Normal file
View File

@ -0,0 +1,11 @@
Supports reading Avro Object Container Format (OCF) files based on the 1.11.0 specification.
Capable of handling null, deflate, and snappy codecs for data compression.
Limitations:
- Schema does not support self-referential types, only built-in types.
- Decimal logical types are not supported for decoding, will just be treated as their primitive type
#### References
- https://avro.apache.org/docs/current/spec.html#Object+Container+Files

View File

@ -13,6 +13,7 @@ import (
) )
//go:embed bencode.jq //go:embed bencode.jq
//go:embed bencode.md
var bencodeFS embed.FS var bencodeFS embed.FS
func init() { func init() {
@ -20,7 +21,7 @@ func init() {
Name: format.BENCODE, Name: format.BENCODE,
Description: "BitTorrent bencoding", Description: "BitTorrent bencoding",
DecodeFn: decodeBencode, DecodeFn: decodeBencode,
Functions: []string{"torepr", "_help"}, Functions: []string{"torepr"},
}) })
interp.RegisterFS(bencodeFS) interp.RegisterFS(bencodeFS)
} }

View File

@ -9,9 +9,3 @@ def _bencode_torepr:
) )
else error("unknown type \(.type)") else error("unknown type \(.type)")
end; end;
def _bencode__help:
{ links: [
{url: "https://wiki.theory.org/BitTorrentSpecification#Bencoding"}
]
};

View File

@ -0,0 +1,8 @@
#### Convert represented value to JSON
```
$ fq -d bencode torepr file.torrent
```
#### References
- https://wiki.theory.org/BitTorrentSpecification#Bencoding

View File

@ -13,6 +13,7 @@ import (
) )
//go:embed bson.jq //go:embed bson.jq
//go:embed bson.md
var bsonFS embed.FS var bsonFS embed.FS
func init() { func init() {
@ -20,7 +21,7 @@ func init() {
Name: format.BSON, Name: format.BSON,
Description: "Binary JSON", Description: "Binary JSON",
DecodeFn: decodeBSON, DecodeFn: decodeBSON,
Functions: []string{"torepr", "_help"}, Functions: []string{"torepr"},
}) })
interp.RegisterFS(bsonFS) interp.RegisterFS(bsonFS)
} }

View File

@ -17,11 +17,3 @@ def _bson_torepr:
| _f | _f
); );
def _bson__help:
{ examples: [
{comment: "BSON as JSON", shell: "fq -d bson torepr file"}
],
links: [
{url: "https://wiki.theory.org/BitTorrentSpecification#Bencoding"}
]
};

14
format/bson/bson.md Normal file
View File

@ -0,0 +1,14 @@
#### Convert represented value to JSON
```
$ fq -d bson torepr file.bson
```
### Filter represented value
```
$ fq -d bson 'torepr | select(.name=="bob")' file.bson
```
#### References
- https://bsonspec.org/spec.html

View File

@ -21,6 +21,7 @@ import (
) )
//go:embed cbor.jq //go:embed cbor.jq
//go:embed cbor.md
var cborFS embed.FS var cborFS embed.FS
func init() { func init() {
@ -28,7 +29,7 @@ func init() {
Name: format.CBOR, Name: format.CBOR,
Description: "Concise Binary Object Representation", Description: "Concise Binary Object Representation",
DecodeFn: decodeCBOR, DecodeFn: decodeCBOR,
Functions: []string{"torepr", "_help"}, Functions: []string{"torepr"},
}) })
interp.RegisterFS(cborFS) interp.RegisterFS(cborFS)
} }

View File

@ -8,10 +8,3 @@ def _cbor_torepr:
elif .major_type == "bytes" then .value | tostring elif .major_type == "bytes" then .value | tostring
else .value | tovalue else .value | tovalue
end; end;
def _cbor__help:
{ links: [
{url: "https://en.wikipedia.org/wiki/CBOR"},
{url: "https://www.rfc-editor.org/rfc/rfc8949.html"}
]
};

9
format/cbor/cbor.md Normal file
View File

@ -0,0 +1,9 @@
#### Convert represented value to JSON
```
$ fq -d cbor torepr file.cbor
```
#### References
- https://en.wikipedia.org/wiki/CBOR
- https://www.rfc-editor.org/rfc/rfc8949.html

View File

@ -86,6 +86,7 @@ const (
JSONL = "jsonl" JSONL = "jsonl"
MACHO = "macho" MACHO = "macho"
MACHO_FAT = "macho_fat" MACHO_FAT = "macho_fat"
MARKDOWN = "markdown"
MATROSKA = "matroska" MATROSKA = "matroska"
MP3 = "mp3" MP3 = "mp3"
MP3_FRAME = "mp3_frame" MP3_FRAME = "mp3_frame"

View File

@ -14,7 +14,7 @@ import (
"github.com/wader/fq/pkg/scalar" "github.com/wader/fq/pkg/scalar"
) )
//go:embed macho.jq //go:embed macho.md
var machoFS embed.FS var machoFS embed.FS
func init() { func init() {
@ -23,7 +23,6 @@ func init() {
Description: "Mach-O macOS executable", Description: "Mach-O macOS executable",
Groups: []string{format.PROBE}, Groups: []string{format.PROBE},
DecodeFn: machoDecode, DecodeFn: machoDecode,
Functions: []string{"_help"},
}) })
interp.RegisterFS(machoFS) interp.RegisterFS(machoFS)
} }

View File

@ -1,9 +0,0 @@
def _macho__help:
{ notes: "Supports decoding vanilla and FAT Mach-O binaries.",
examples: [
{comment: "Select 64bit load segments", shell: "fq '.load_commands[] | select(.cmd==\"segment_64\")' file"}
],
links: [
{url: "https://github.com/aidansteele/osx-abi-macho-file-format-reference"}
]
};

10
format/macho/macho.md Normal file
View File

@ -0,0 +1,10 @@
Supports decoding vanilla and FAT Mach-O binaries.
#### Select 64bit load segments
```sh
$ fq '.load_commands[] | select(.cmd=="segment_64")' file
```
#### References
- https://github.com/aidansteele/osx-abi-macho-file-format-reference

319
format/markdown/markdown.go Normal file
View File

@ -0,0 +1,319 @@
package markdown
import (
"embed"
"fmt"
"io"
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/ast"
"github.com/wader/fq/format"
"github.com/wader/fq/pkg/bitio"
"github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/interp"
"github.com/wader/fq/pkg/scalar"
)
//go:embed markdown.jq
var markdownFS embed.FS
func init() {
interp.RegisterFormat(decode.Format{
Name: format.MARKDOWN,
Description: "Markdown",
DecodeFn: decodeMarkdown,
Functions: []string{"_todisplay"},
})
interp.RegisterFS(markdownFS)
}
func decodeMarkdown(d *decode.D, _ any) any {
b, err := io.ReadAll(bitio.NewIOReader(d.RawLen(d.Len())))
if err != nil {
panic(err)
}
var s scalar.S
s.Actual = node(markdown.Parse(b, nil))
d.Value.V = &s
d.Value.Range.Len = d.Len()
return nil
}
func stringSlice[T string | []byte](ss []T) []any {
var vs []any
for _, e := range ss {
vs = append(vs, string(e))
}
return vs
}
func sliceMap[F, T any](vs []F, fn func(F) T) []T {
ts := make([]T, len(vs))
for i, v := range vs {
ts[i] = fn(v)
}
return ts
}
func intSlice[T ~int](ss []T) []any {
var vs []any
for _, e := range ss {
vs = append(vs, e)
}
return vs
}
func attr(v map[string]any, attr *ast.Attribute) {
if attr == nil {
return
}
v["id"] = string(attr.ID)
var as []any
for _, a := range attr.Attrs {
as = append(as, string(a))
}
v["attrs"] = as
var cs []any
for _, a := range attr.Classes {
cs = append(cs, string(a))
}
v["classes"] = cs
}
func leaf(v map[string]any, typ string, l ast.Leaf) {
v["type"] = typ
v["literal"] = string(l.Literal)
attr(v, l.Attribute)
}
func container(v map[string]any, typ string, c ast.Container) {
v["type"] = typ
v["literal"] = string(c.Literal)
var cs []any
children := c.GetChildren()
for _, n := range children {
cv := node(n)
if cv != nil {
cs = append(cs, node(n))
}
}
v["children"] = cs
attr(v, c.Attribute)
}
func listType(t ast.ListType) []any {
var vs []any
if t&ast.ListTypeOrdered == ast.ListTypeOrdered {
vs = append(vs, "ordered")
}
if t%ast.ListTypeOrdered == ast.ListTypeOrdered {
vs = append(vs, "ordered")
}
if t%ast.ListTypeDefinition == ast.ListTypeDefinition {
vs = append(vs, "definition")
}
if t%ast.ListTypeTerm == ast.ListTypeTerm {
vs = append(vs, "term")
}
if t%ast.ListItemContainsBlock == ast.ListItemContainsBlock {
vs = append(vs, "contains_block")
}
if t%ast.ListItemBeginningOfList == ast.ListItemBeginningOfList {
vs = append(vs, "beginning_of_list")
}
if t%ast.ListItemEndOfList == ast.ListItemEndOfList {
vs = append(vs, "end_of_list")
}
return vs
}
func node(n ast.Node) any {
v := map[string]any{}
switch n := n.(type) {
case *ast.Text:
if n.Leaf.Attribute == nil {
if len(n.Leaf.Literal) > 0 {
return string(n.Leaf.Literal)
}
// skip
return nil
}
case *ast.Softbreak:
leaf(v, "softbreak", n.Leaf)
case *ast.Hardbreak:
leaf(v, "hardbreak", n.Leaf)
case *ast.NonBlockingSpace:
leaf(v, "nbsp", n.Leaf)
case *ast.Emph:
container(v, "em", n.Container)
case *ast.Strong:
container(v, "strong", n.Container)
case *ast.Del:
container(v, "del", n.Container)
case *ast.BlockQuote:
container(v, "blockquote", n.Container)
case *ast.Aside:
container(v, "aside", n.Container)
case *ast.Link:
container(v, "link", n.Container)
v["destination"] = string(n.Destination)
v["title"] = string(n.Title)
v["note_id"] = n.NoteID
v["deferred_id"] = string(n.DeferredID)
v["additional_attributes"] = stringSlice(n.AdditionalAttributes)
case *ast.CrossReference:
container(v, "cross_reference", n.Container)
v["destination"] = string(n.Destination)
case *ast.Citation:
leaf(v, "citation", n.Leaf)
v["destination"] = stringSlice(n.Destination)
v["type"] = sliceMap(n.Type, func(v ast.CitationTypes) string {
switch v {
case ast.CitationTypeNone:
return "none"
case ast.CitationTypeSuppressed:
return "suppressed"
case ast.CitationTypeInformative:
return "informative"
case ast.CitationTypeNormative:
return "normative"
default:
return "unknown"
}
})
v["type"] = intSlice(n.Type)
v["suffix"] = stringSlice(n.Suffix)
case *ast.Image:
container(v, "image", n.Container)
v["destination"] = string(n.Destination)
v["title"] = string(n.Title)
case *ast.Code:
leaf(v, "code", n.Leaf)
case *ast.CodeBlock:
leaf(v, "code_block", n.Leaf)
v["is_fenced"] = n.IsFenced
v["info"] = string(n.Info)
if n.FenceChar != 0 {
v["fence_char"] = string(n.FenceChar)
}
v["fence_length"] = n.FenceLength
v["fence_offset"] = n.FenceOffset
case *ast.Caption:
container(v, "caption", n.Container)
case *ast.CaptionFigure:
container(v, "caption_figure", n.Container)
v["heading_id"] = n.HeadingID
case *ast.Document:
container(v, "document", n.Container)
case *ast.Paragraph:
container(v, "paragraph", n.Container)
case *ast.HTMLSpan:
leaf(v, "html_span", n.Leaf)
case *ast.HTMLBlock:
leaf(v, "html_block", n.Leaf)
case *ast.Heading:
container(v, "heading", n.Container)
v["level"] = n.Level
v["heading_id"] = n.HeadingID
v["is_titleblock"] = n.IsTitleblock
v["is_special"] = n.IsSpecial
case *ast.HorizontalRule:
leaf(v, "hr", n.Leaf)
case *ast.List:
container(v, "list", n.Container)
v["list_flags"] = listType(n.ListFlags)
v["tight"] = n.Tight
if n.BulletChar != 0 {
v["bullet_char"] = string(n.BulletChar)
}
if n.Delimiter != 0 {
v["delimiter"] = string(n.Delimiter)
}
v["start"] = n.Start
v["ref_link"] = string(n.RefLink)
v["is_footnotes_list"] = n.IsFootnotesList
case *ast.ListItem:
container(v, "list_item", n.Container)
v["list_flags"] = listType(n.ListFlags)
v["tight"] = n.Tight
if n.BulletChar != 0 {
v["bullet_char"] = string(n.BulletChar)
}
if n.Delimiter != 0 {
v["delimiter"] = string(n.Delimiter)
}
v["ref_link"] = string(n.RefLink)
v["is_footnotes_list"] = n.IsFootnotesList
case *ast.Table:
container(v, "table", n.Container)
case *ast.TableCell:
container(v, "table_cell", n.Container)
v["is_header"] = n.IsHeader
v["align"] = n.Align.String()
v["col_span"] = n.ColSpan
case *ast.TableHeader:
container(v, "table_header", n.Container)
case *ast.TableBody:
container(v, "table_body", n.Container)
case *ast.TableRow:
container(v, "table_row", n.Container)
case *ast.TableFooter:
container(v, "table_footer", n.Container)
case *ast.Math:
leaf(v, "math", n.Leaf)
case *ast.MathBlock:
container(v, "math_block", n.Container)
case *ast.DocumentMatter:
container(v, "document_matter", n.Container)
v["matter"] = func(v ast.DocumentMatters) string {
switch v {
case ast.DocumentMatterNone:
return "none"
case ast.DocumentMatterFront:
return "front"
case ast.DocumentMatterMain:
return "main"
case ast.DocumentMatterBack:
return "back"
default:
return "unknown"
}
}(n.Matter)
case *ast.Callout:
leaf(v, "callout", n.Leaf)
v["id"] = string(n.ID)
case *ast.Index:
leaf(v, "index", n.Leaf)
v["primary"] = n.Primary
v["item"] = string(n.Item)
v["subitem"] = string(n.Subitem)
v["id"] = n.ID
case *ast.Subscript:
leaf(v, "subscript", n.Leaf)
case *ast.Superscript:
leaf(v, "superscript", n.Leaf)
case *ast.Footnotes:
container(v, "footnotes", n.Container)
default:
panic(fmt.Sprintf("unknown node %T", node))
}
for k, e := range v {
if s, ok := e.(string); ok && s == "" {
delete(v, k)
}
}
return v
}

View File

@ -0,0 +1,52 @@
def _markdown__todisplay: tovalue;
def word_break($width):
def _f($a; $acc; $l):
( $a[0] as $w
| ($w // "" | length) as $wl
| if $w == null then $acc
elif ($l + $wl) >= $width then
( $acc
, _f($a[1:]; [$w]; $wl)
)
else _f($a[1:]; $acc+[$w]; $l+$wl)
end
);
( [_f([splits("\\s{1,}")]; []; 0)]
| map(join(" "))
);
def _markdown_to_text($width; $header_depth):
def lb: if $width > 0 then word_break($width) | join("\n") end;
def _f($pln):
if type == "string" then gsub("\n"; " ")
elif .type == "document" then .children[] | _f("\n\n")
elif .type == "heading" then "#" * (.level+$header_depth), " ", (.children[] | _f("\n\n")), "\n"
elif .type == "paragraph" then
( ( [.children[] | _f("\n\n")]
| join("")
| lb
)
, $pln
)
elif .type == "link" then
( ( [ .children[]
| _f("")
]
| join("")
) as $text
| $text
, if $text != .destination then " (", .destination, ")"
else empty
end
)
elif .type == "code_block" then "\n", (" ", .literal | split("\n") | join("\n ")), "\n"
elif .type == "code" then .literal
elif .type == "list" then (.children[] | _f("\n\n")), "\n" # TODO: delim
elif .type == "list_item" then .bullet_char, " ", (.children[] | _f("\n"))
elif .type == "html_span" then .literal | gsub("<br>"; "\n") # TODO: more?
else empty
end;
[_f("\n\n")] | join("");
def _markdown_to_text:
_markdown_to_text(-1; 0);

316
format/markdown/testdata/test.fqtest vendored Normal file
View File

@ -0,0 +1,316 @@
$ fq -d markdown . test.md
{
"children": [
{
"children": [
"Before"
],
"type": "paragraph"
},
{
"children": [
"header 1"
],
"is_special": false,
"is_titleblock": false,
"level": 1,
"type": "heading"
},
{
"children": [
"Paragraph with ",
{
"children": [
"bold"
],
"type": "strong"
},
" and ",
{
"children": [
"italic"
],
"type": "em"
},
"\non\nmultiple\nlines."
],
"type": "paragraph"
},
{
"children": [
{
"children": [
"Some citation"
],
"type": "paragraph"
}
],
"type": "blockquote"
},
{
"children": [
"A footnote",
{
"additional_attributes": [],
"children": [
"^1"
],
"destination": "footnote1",
"note_id": 0,
"type": "link"
},
" and this also",
{
"additional_attributes": [],
"children": [
"^note"
],
"destination": "footnote2",
"note_id": 0,
"type": "link"
}
],
"type": "paragraph"
},
{
"children": [
"header 2"
],
"is_special": false,
"is_titleblock": false,
"level": 2,
"type": "heading"
},
{
"fence_length": 0,
"fence_offset": 0,
"info": "jq",
"is_fenced": true,
"literal": "code\nblock\n",
"type": "code_block"
},
{
"fence_length": 0,
"fence_offset": 0,
"is_fenced": false,
"literal": "also\ncode\n",
"type": "code_block"
},
{
"children": [
"header 3"
],
"is_special": false,
"is_titleblock": false,
"level": 3,
"type": "heading"
},
{
"children": [
"Some text with ",
{
"literal": "code",
"type": "code"
}
],
"type": "paragraph"
},
{
"children": [
"header 4"
],
"is_special": false,
"is_titleblock": false,
"level": 4,
"type": "heading"
},
{
"children": [
"Some text ",
{
"additional_attributes": [],
"children": [
"with a link"
],
"destination": "http://host/path",
"note_id": 0,
"type": "link"
}
],
"type": "paragraph"
},
{
"children": [
"An image ",
{
"children": [
"img alt text"
],
"destination": "path/image.png",
"type": "image"
}
],
"type": "paragraph"
},
{
"children": [
"header 5"
],
"is_special": false,
"is_titleblock": false,
"level": 5,
"type": "heading"
},
{
"children": [
{
"bullet_char": "-",
"children": [
{
"children": [
"list of"
],
"type": "paragraph"
}
],
"delimiter": ".",
"is_footnotes_list": false,
"list_flags": [],
"tight": false,
"type": "list_item"
},
{
"bullet_char": "-",
"children": [
{
"children": [
"things"
],
"type": "paragraph"
}
],
"delimiter": ".",
"is_footnotes_list": false,
"list_flags": [],
"tight": false,
"type": "list_item"
}
],
"delimiter": ".",
"is_footnotes_list": false,
"list_flags": [],
"start": 0,
"tight": true,
"type": "list"
},
{
"children": [
"a table"
],
"type": "paragraph"
},
{
"children": [
{
"children": [
{
"children": [
{
"children": [
"a"
],
"col_span": 0,
"is_header": true,
"type": "table_cell"
},
{
"children": [
"b"
],
"col_span": 0,
"is_header": true,
"type": "table_cell"
},
{
"children": [
"c"
],
"col_span": 0,
"is_header": true,
"type": "table_cell"
}
],
"type": "table_row"
}
],
"type": "table_header"
},
{
"children": [
{
"children": [
{
"children": [
"1"
],
"col_span": 0,
"is_header": false,
"type": "table_cell"
},
{
"children": [
"2"
],
"col_span": 0,
"is_header": false,
"type": "table_cell"
},
{
"children": [
"3"
],
"col_span": 0,
"is_header": false,
"type": "table_cell"
}
],
"type": "table_row"
}
],
"type": "table_body"
}
],
"type": "table"
},
{
"children": [
"header 6"
],
"is_special": false,
"is_titleblock": false,
"level": 6,
"type": "heading"
},
{
"children": [
"Some text with line ",
{
"literal": "<br>",
"type": "html_span"
},
" break and ",
{
"literal": "<b>",
"type": "html_span"
},
"bold",
{
"literal": "</b>",
"type": "html_span"
}
],
"type": "paragraph"
}
],
"type": "document"
}

50
format/markdown/testdata/test.md vendored Normal file
View File

@ -0,0 +1,50 @@
Before
# header 1
Paragraph with **bold** and *italic*
on
multiple
lines.
> Some citation
A footnote[^1] and this also[^note]
## header 2
```jq
code
block
```
also
code
### header 3
Some text with `code`
#### header 4
Some text [with a link](http://host/path)
An image ![img alt text](path/image.png)
##### header 5
- list of
- things
a table
| a | b | c |
| --- | --- | --- |
| 1 | 2 | 3 |
###### header 6
Some text with line <br> break and <b>bold</b>
[^1]: footnote1
[^note]: footnote2

View File

@ -27,6 +27,7 @@ import (
) )
//go:embed matroska.jq //go:embed matroska.jq
//go:embed matroska.md
var matroskaFS embed.FS var matroskaFS embed.FS
var aacFrameFormat decode.Group var aacFrameFormat decode.Group
@ -78,7 +79,6 @@ func init() {
{Names: []string{format.VP9_CFM}, Group: &vp9CFMFormat}, {Names: []string{format.VP9_CFM}, Group: &vp9CFMFormat},
{Names: []string{format.VP9_FRAME}, Group: &vp9FrameFormat}, {Names: []string{format.VP9_FRAME}, Group: &vp9FrameFormat},
}, },
Functions: []string{"_help"},
}) })
interp.RegisterFS(matroskaFS) interp.RegisterFS(matroskaFS)

View File

@ -12,17 +12,3 @@ def matroska_path:
| format_root | format_root
| matroska_path($c) | matroska_path($c)
); );
def _matroska__help:
{ examples: [
{comment: "Lookup element decode value using `matroska_path`", expr: "matroska_path(\".Segment.Tracks[0)\""},
{comment: "Return `matroska_path` string for a box decode value", expr: "grep_by(.id == \"Tracks\") | matroska_path"}
],
links: [
{url: "https://tools.ietf.org/html/draft-ietf-cellar-ebml-00"},
{url: "https://matroska.org/technical/specs/index.html"},
{url: "https://www.matroska.org/technical/basics.html"},
{url: "https://www.matroska.org/technical/codec_specs.html"},
{url: "https://wiki.xiph.org/MatroskaOpus"}
]
};

View File

@ -0,0 +1,18 @@
#### Lookup element path using `matroska_path`
```sh
$ fq 'matroska_path(".Segment.Tracks[0)")' file.mkv
```
#### Get element path using `matroska_path`
```sh
$ fq 'grep_by(.id == "Tracks") | matroska_path' file.mkv
```
#### References
- https://tools.ietf.org/html/draft-ietf-cellar-ebml-00
- https://matroska.org/technical/specs/index.html
- https://www.matroska.org/technical/basics.html
- https://www.matroska.org/technical/codec_specs.html
- https://wiki.xiph.org/MatroskaOpus

View File

@ -26,6 +26,7 @@ import (
) )
//go:embed mp4.jq //go:embed mp4.jq
//go:embed mp4.md
var mp4FS embed.FS var mp4FS embed.FS
var aacFrameFormat decode.Group var aacFrameFormat decode.Group
@ -55,7 +56,7 @@ var vpxCCRFormat decode.Group
func init() { func init() {
interp.RegisterFormat(decode.Format{ interp.RegisterFormat(decode.Format{
Name: format.MP4, Name: format.MP4,
Description: "ISOBMFF MPEG-4 part 12 and similar", Description: "ISOBMFF, QuickTime and similar",
Groups: []string{ Groups: []string{
format.PROBE, format.PROBE,
format.IMAGE, // avif format.IMAGE, // avif
@ -90,7 +91,6 @@ func init() {
{Names: []string{format.VP9_FRAME}, Group: &vp9FrameFormat}, {Names: []string{format.VP9_FRAME}, Group: &vp9FrameFormat},
{Names: []string{format.VPX_CCR}, Group: &vpxCCRFormat}, {Names: []string{format.VPX_CCR}, Group: &vpxCCRFormat},
}, },
Functions: []string{"_help"},
}) })
interp.RegisterFS(mp4FS) interp.RegisterFS(mp4FS)
} }

View File

@ -12,15 +12,3 @@ def mp4_path:
| format_root | format_root
| mp4_path($c) | mp4_path($c)
); );
def _mp4__help:
{ notes: "Support `mp4_path`",
examples: [
{comment: "Lookup box decode value using `mp4_path`", expr: "mp4_path(\".moov.trak[1]\")"},
{comment: "Return `mp4_path` string for a box decode value", expr: "grep_by(.type == \"trak\") | mp4_path"}
],
links: [
{title: "ISO/IEC base media file format (MPEG-4 Part 12)", url: "https://en.wikipedia.org/wiki/ISO/IEC_base_media_file_format"},
{title: "Quicktime file format", url: "https://developer.apple.com/standards/qtff-2001.pdf"}
]
};

36
format/mp4/mp4.md Normal file
View File

@ -0,0 +1,36 @@
#### `mp4_path($path)` - Lookup mp4 box using a mp4 box path.
```sh
# <decode value box> | mp4_path($path) -> <decode value box>
$ fq 'mp4_path(".moov.trak[1]")' file.mp4
```
#### `mp4_path` - Return mp4 box path for a decode value box.
```sh
# <decode value box> | mp4_path -> string
$ fq 'grep_by(.type == "trak") | mp4_path' file.mp4
```
#### Force decode a single box
```sh
$ fq -n '"AAAAHGVsc3QAAAAAAAAAAQAAADIAAAQAAAEAAA==" | frombase64 | mp4({force:true}) | d'
```
#### Don't decode samples and manually decode first sample for first track as a `aac_frame`
```sh
$ fq -o decode_samples=false '.tracks[0].samples[0] | aac_frame | d' file.mp4
```
#### Entries for first edit list as values
```sh
$ fq 'first(grep_by(.type=="elst").entries) | tovalue' file.mp4
```
#### References
- [ISO/IEC base media file format (MPEG-4 Part 12)](https://en.wikipedia.org/wiki/ISO/IEC_base_media_file_format)
- [Quicktime file format](https://developer.apple.com/standards/qtff-2001.pdf)

View File

@ -14,6 +14,7 @@ import (
) )
//go:embed msgpack.jq //go:embed msgpack.jq
//go:embed msgpack.md
var msgPackFS embed.FS var msgPackFS embed.FS
func init() { func init() {
@ -21,7 +22,7 @@ func init() {
Name: format.MSGPACK, Name: format.MSGPACK,
Description: "MessagePack", Description: "MessagePack",
DecodeFn: decodeMsgPack, DecodeFn: decodeMsgPack,
Functions: []string{"torepr", "_help"}, Functions: []string{"torepr"},
}) })
interp.RegisterFS(msgPackFS) interp.RegisterFS(msgPackFS)
} }

View File

@ -9,8 +9,3 @@ def _msgpack_torepr:
else .value | tovalue else .value | tovalue
end; end;
def _msgpack__help:
{ links: [
{url: "https://github.com/msgpack/msgpack/blob/master/spec.md"}
]
};

View File

@ -0,0 +1,8 @@
#### Convert represented value to JSON
```
$ fq -d msgpack torepr file.msgpack
```
#### References
- https://github.com/msgpack/msgpack/blob/master/spec.md

View File

@ -12,7 +12,7 @@ import (
"github.com/wader/fq/pkg/scalar" "github.com/wader/fq/pkg/scalar"
) )
//go:embed protobuf.jq //go:embed protobuf.md
var protobufFS embed.FS var protobufFS embed.FS
func init() { func init() {
@ -20,7 +20,6 @@ func init() {
Name: format.PROTOBUF, Name: format.PROTOBUF,
Description: "Protobuf", Description: "Protobuf",
DecodeFn: protobufDecode, DecodeFn: protobufDecode,
Functions: []string{"_help"},
}) })
interp.RegisterFS(protobufFS) interp.RegisterFS(protobufFS)
} }

View File

@ -1,8 +0,0 @@
def _protobuf__help:
{ examples: [
{comment: "Can be used to decode sub messages", shell: "fq -d protobuf '.fields[6].wire_value | protobuf | d'"}
],
links: [
{url: "https://developers.google.com/protocol-buffers/docs/encoding"}
]
};

View File

@ -0,0 +1,8 @@
#### Can decode sub messages
```sh
$ fq -d protobuf '.fields[6].wire_value | protobuf | d' file
```
#### References
- https://developers.google.com/protocol-buffers/docs/encoding

View File

@ -21,7 +21,7 @@ import (
var rtmpAmf0Group decode.Group var rtmpAmf0Group decode.Group
var rtmpMpegASCFormat decode.Group var rtmpMpegASCFormat decode.Group
//go:embed rtmp.jq //go:embed rtmp.md
var rtmpFS embed.FS var rtmpFS embed.FS
func init() { func init() {
@ -36,7 +36,6 @@ func init() {
{Names: []string{format.AMF0}, Group: &rtmpAmf0Group}, {Names: []string{format.AMF0}, Group: &rtmpAmf0Group},
{Names: []string{format.MPEG_ASC}, Group: &rtmpMpegASCFormat}, {Names: []string{format.MPEG_ASC}, Group: &rtmpMpegASCFormat},
}, },
Functions: []string{"_help"},
}) })
interp.RegisterFS(rtmpFS) interp.RegisterFS(rtmpFS)
} }

View File

@ -1,7 +0,0 @@
def _rtmp__help:
{ notes: "Current only supports plain RTMP (not RTMPT or encrypted variants etc) with AMF0 (not AMF3).",
links: [
{url: "https://rtmp.veriskope.com/docs/spec/"},
{url: "https://rtmp.veriskope.com/pdf/video_file_format_spec_v10.pdf"}
]
};

5
format/rtmp/rtmp.md Normal file
View File

@ -0,0 +1,5 @@
Current only supports plain RTMP (not RTMPT or encrypted variants etc) with AMF0 (not AMF3).
#### References
- https://rtmp.veriskope.com/docs/spec/
- https://rtmp.veriskope.com/pdf/video_file_format_spec_v10.pdf

View File

@ -29,6 +29,7 @@ import (
) )
//go:embed xml.jq //go:embed xml.jq
//go:embed xml.md
var xmlFS embed.FS var xmlFS embed.FS
func init() { func init() {
@ -43,7 +44,7 @@ func init() {
Array: false, Array: false,
AttributePrefix: "@", AttributePrefix: "@",
}, },
Functions: []string{"_todisplay", "_help"}, Functions: []string{"_todisplay"},
}) })
interp.RegisterFS(xmlFS) interp.RegisterFS(xmlFS)
interp.RegisterFunc1("toxml", toXML) interp.RegisterFunc1("toxml", toXML)

View File

@ -1,8 +1,2 @@
def toxml: toxml(null); def toxml: toxml(null);
def _xml__todisplay: tovalue; def _xml__todisplay: tovalue;
def _xml__help:
{ links: [
{title: "xml.com's Converting Between XML and JSON", url: "https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html"}
]
};

2
format/xml/xml.md Normal file
View File

@ -0,0 +1,2 @@
#### References
- [xml.com's Converting Between XML and JSON](https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html)

View File

@ -15,7 +15,7 @@ import (
"github.com/wader/fq/pkg/scalar" "github.com/wader/fq/pkg/scalar"
) )
//go:embed zip.jq //go:embed zip.md
var zipFS embed.FS var zipFS embed.FS
var probeFormat decode.Group var probeFormat decode.Group
@ -32,7 +32,6 @@ func init() {
Dependencies: []decode.Dependency{ Dependencies: []decode.Dependency{
{Names: []string{format.PROBE}, Group: &probeFormat}, {Names: []string{format.PROBE}, Group: &probeFormat},
}, },
Functions: []string{"_help"},
}) })
interp.RegisterFS(zipFS) interp.RegisterFS(zipFS)
} }

View File

@ -1,6 +0,0 @@
def _zip__help:
{ notes: "Supports ZIP64.",
links: [
{url: "https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"}
]
};

5
format/zip/zip.md Normal file
View File

@ -0,0 +1,5 @@
Supports ZIP64.
#### References
- https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
- https://opensource.apple.com/source/zip/zip-6/unzip/unzip/proginfo/extra.fld

4
go.mod
View File

@ -25,6 +25,10 @@ require (
// bump: gomod-golang-snappy link "Source diff $CURRENT..$LATEST" https://github.com/golang/snappy/compare/v$CURRENT..v$LATEST // bump: gomod-golang-snappy link "Source diff $CURRENT..$LATEST" https://github.com/golang/snappy/compare/v$CURRENT..v$LATEST
github.com/golang/snappy v0.0.4 github.com/golang/snappy v0.0.4
// has no tags
// go get -d github.com/gomarkdown/markdown@master && go mod tidy
github.com/gomarkdown/markdown v0.0.0-20220627144906-e9a81102ebeb
// has no tags yet // has no tags yet
// bump-disabled: gomod-gopacket /github\.com\/gopacket\/gopacket v(.*)/ https://github.com/gopacket/gopacket.git|^1 // bump-disabled: gomod-gopacket /github\.com\/gopacket\/gopacket v(.*)/ https://github.com/gopacket/gopacket.git|^1
// bump-disabled: gomod-gopacket command go get -d github.com/gopacket/gopacket@v$LATEST && go mod tidy // bump-disabled: gomod-gopacket command go get -d github.com/gopacket/gopacket@v$LATEST && go mod tidy

2
go.sum
View File

@ -4,6 +4,8 @@ github.com/creasty/defaults v1.6.0 h1:ltuE9cfphUtlrBeomuu8PEyISTXnxqkBIoQfXgv7BS
github.com/creasty/defaults v1.6.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM= github.com/creasty/defaults v1.6.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomarkdown/markdown v0.0.0-20220627144906-e9a81102ebeb h1:5b/eFaSaKPFG9ygDBaPKkydKU5nFJYk08g9jPIVogMg=
github.com/gomarkdown/markdown v0.0.0-20220627144906-e9a81102ebeb/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
github.com/gopacket/gopacket v0.0.0-20220819214934-ee81b8c880da h1:AAwDU9N39fQNYUtg270aiU6N7U2ZVsGZKiRwsCMsWEo= github.com/gopacket/gopacket v0.0.0-20220819214934-ee81b8c880da h1:AAwDU9N39fQNYUtg270aiU6N7U2ZVsGZKiRwsCMsWEo=
github.com/gopacket/gopacket v0.0.0-20220819214934-ee81b8c880da/go.mod h1:DlRRfaM/QjAu2ADqraIure1Eif0HpNL8hmyVQ+qci5Y= github.com/gopacket/gopacket v0.0.0-20220819214934-ee81b8c880da/go.mod h1:DlRRfaM/QjAu2ADqraIure1Eif0HpNL8hmyVQ+qci5Y=
github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921iRkU= github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921iRkU=

View File

@ -153,23 +153,6 @@ def paste:
) )
end; end;
# very simple markdown to text converter
# assumes very basic markdown as input
def _markdown_to_text:
( .
# ```
# code
# ```
# -> code
| gsub("\\n```\\n"; "\n"; "m")
# #, ##, ###, ... -> #
| gsub("(?<line>\\n)?#+(?<title>.*)\\n"; "\(.line // "")#\(.title)\n"; "m")
# [title](url) -> title (url)
| gsub("\\[(?<title>.*)\\]\\((?<url>.*)\\)"; "\(.title) (\(.url))")
# `code` -> code
| gsub("`(?<code>.*)`"; .code)
);
def expr_to_path: _expr_to_path; def expr_to_path: _expr_to_path;
def path_to_expr: _path_to_expr; def path_to_expr: _path_to_expr;

View File

@ -64,14 +64,6 @@ def _help_format_enrich($arg0; $f; $include_basic):
, {comment: "Decode value as \($f.name)", expr: "\($f.name)"} , {comment: "Decode value as \($f.name)", expr: "\($f.name)"}
] ]
end end
| (($f.functions // []) | map(select(startswith("_") | not))) as $public_functions
| if ($public_functions | length) > 0 then
.examples +=
[ $public_functions[]
| {comment: "Supports `\(.)`", shell: "fq -d \($f.name) torepr file"}
, {comment: "Supports `\(.)`", expr: "\($f.name) | torepr"}
]
end
| if $f.decode_in_arg then | if $f.decode_in_arg then
.examples += .examples +=
[ { comment: "Decode file using \($f.name) options" [ { comment: "Decode file using \($f.name) options"
@ -146,13 +138,14 @@ def _help($arg0; $topic):
elif _registry.formats | has($topic) then elif _registry.formats | has($topic) then
( _registry.formats[$topic] as $f ( _registry.formats[$topic] as $f
| (_format_func($f.name; "_help")? // {} | _help_format_enrich($arg0; $f; true)) as $fhelp | (_format_func($f.name; "_help")? // {} | _help_format_enrich($arg0; $f; true)) as $fhelp
| ((_registry.files[][] | select(.name=="\($topic).md").data) // false) as $doc
| "\($f.name): \($f.description) decoder" | "\($f.name): \($f.description) decoder"
, ($fhelp.notes | if . then _markdown_to_text else empty end)
, if $f.decode_in_arg then , if $f.decode_in_arg then
( $f.decode_in_arg ( $f.decode_in_arg
| to_entries | to_entries
| map([" \(.key)=\(.value) ", $f.decode_in_arg_doc[.key]]) | map([" \(.key)=\(.value) ", $f.decode_in_arg_doc[.key]])
| "Options:" | "# Options"
, ""
, table( , table(
.; .;
map( map(
@ -167,28 +160,19 @@ def _help($arg0; $topic):
) )
else empty else empty
end end
, "Examples:" , ""
, "# Decode examples"
, ""
, ( $fhelp.examples[] , ( $fhelp.examples[]
| " # \(.comment | _markdown_to_text)" | " # \(.comment)"
, if .shell then " $ \(.shell)" , if .shell then " $ \(.shell)"
elif .expr then " ... | \(.expr)" elif .expr then " ... | \(.expr)"
else empty else empty
end end
) )
, if isempty($f.functions | select(. == "torepr")) | not then , ""
( "Supports torepr:" # TODO: [:-1] hack to remove extra newline as we use println later
, " ... | \($f.name) | torepr" , if $doc then $doc | markdown | _markdown_to_text(options.width; -3)[:-1]
)
else empty
end
, if $fhelp.links then
( "References and links"
, ( $fhelp.links[]
| if .title then " \(.title) \(.url)"
else " \(.url)"
end
)
)
else empty else empty
end end
) )

View File

@ -162,10 +162,11 @@ json JavaScript Object Notation
jsonl JavaScript Object Notation Lines jsonl JavaScript Object Notation Lines
macho Mach-O macOS executable macho Mach-O macOS executable
macho_fat Fat Mach-O macOS executable (multi-architecture) macho_fat Fat Mach-O macOS executable (multi-architecture)
markdown Markdown
matroska Matroska file matroska Matroska file
mp3 MP3 file mp3 MP3 file
mp3_frame MPEG audio layer 3 frame mp3_frame MPEG audio layer 3 frame
mp4 ISOBMFF MPEG-4 part 12 and similar mp4 ISOBMFF, QuickTime and similar
mpeg_asc MPEG-4 Audio Specific Config mpeg_asc MPEG-4 Audio Specific Config
mpeg_es MPEG Elementary Stream mpeg_es MPEG Elementary Stream
mpeg_pes MPEG Packetized elementary stream mpeg_pes MPEG Packetized elementary stream