Šķîþ ţö ḿàîñ çöñţéñţ

Šķéļéţöñ šţöŕé àñđ šţŕéàḿîñĝ

Îḿþļéḿéñţàţîöñ đéţàîļš ƒöŕ ţĥé SkeletonStore ƒŕàḿéŵöŕķ ţýþé, ţĥé šéàḿ ţĥàţ ŵîŕéš îţ îñţö à ŕüñ, àñđ ţĥé šţŕéàḿîñĝ þŕöţöçöļ ţĥàţ ļéţš à ŕéàđéŕ àñđ à ŵŕîţéŕ šĥàŕé îţ çöñçüŕŕéñţļý. Þàŕéñţ ÀĐ: É-02 (ţĥé šķéļéţöñ šţöŕé; šţŕéàḿîñĝ ŕéàđéŕš àñđ ƃöüñđéđ-ḿéḿöŕý Î/Ö).

ŠķéļéţöñŠţöŕé (core/format/skeleton.go)

Àñ àþþéñđ-öñļý šţöŕé öƒ ţýþéđ éñţŕîéš. Ţĥé ŕéàđéŕ ŵŕîţéš éñţŕîéš đüŕîñĝ éẋţŕàçţîöñ; ţĥé ŵŕîţéŕ ŕéàđš ţĥéḿ đüŕîñĝ ŕéçöñšţŕüçţîöñ. Ţĥé þîþéļîñé ñéṽéŕ šééš ţĥé šķéļéţöñ; îţ çàŕŕîéš öñļý ƃļöçķš.

Éñţŕý ƒöŕḿàţ

Éàçĥ éñţŕý îš:

[type:1 byte] [length:4 bytes big-endian] [data:N bytes]
ŢýþéÇöñšţàñţĐàţà
0SkeletonTextÑöñ-ţŕàñšļàţàƃļé ŕàŵ ƃýţéš
1SkeletonRefƂļöçķ ÎĐ àš à ÜŢƑ-8 šţŕîñĝ
2SkeletonLangŠöüŕçé-ļöçàļé lang / xml:lang àţţŕîƃüţé ṽàļüé (ţĥé ŕàŵ ƃýţéš ƃéţŵééñ ţĥé ǫüöţéš), šþļîçéđ ƒöŕ ļàñĝüàĝé ŕéţàŕĝéţîñĝ
3SkeletonOriginalEncodeSkeletonPair(rendered, original): ţĥé ţéẋţ ţĥé ñéẋţ ŕéƒ ŕéñđéŕš ţö ŵĥîļé üñéđîţéđ, àñđ ţĥé šöüŕçé ƃýţéš ţö ŕéþļàý îñšţéàđ
4SkeletonTrimmedEncodeSkeletonPair(rendered, trimmed): ţĥé ţéẋţ ţĥé þŕéṽîöüš ŕéƒ ŕéñđéŕéđ ţö, àñđ ţĥé ƃýţéš ţĥé ŕéàđéŕ ţŕîḿḿéđ àƒţéŕ îţ
5SkeletonInsertedƂýţéš ţĥé ŕéàđéŕ àđđš ţö ţĥé đöçüḿéñţ ţĥàţ îţš šöüŕçé đöéš ñöţ ĥöļđ

Lang ļéţš à ŵŕîţéŕ ŕéţàŕĝéţ ţĥé đöçüḿéñţ ļàñĝüàĝé: ŵĥéñ ţĥé šţöŕéđ ṽàļüé îš ţĥé šàḿé ļàñĝüàĝé àš ţĥé šöüŕçé ļöçàļé îţ éḿîţš ţĥé ţàŕĝéţ ļöçàļé, öţĥéŕŵîšé îţ éḿîţš ţĥé šţöŕéđ ṽàļüé ṽéŕƃàţîḿ. Ţĥé ĤŢḾĻ àñđ ÖþéñẊḾĻ ŕéàđéŕš éḿîţ îţ. À ŵŕîţéŕ ţĥàţ đöéš ñöţ üñđéŕšţàñđ àñ éñţŕý ţýþé ḿüšţ ţŕéàţ îţ àš îñéŕţ; éḿîţţîñĝ ñöţĥîñĝ ŵöüļđ đŕöþ ţĥé àţţŕîƃüţé ṽàļüé.

Inserted ḿàŕķš ƃýţéš ţĥé öüţþüţ ñééđš àñđ ţĥé šöüŕçé ļàçķš: ţĥé ĤŢḾĻ ŕéàđéŕ ŵŕîţéš ţĥé Content-Type ḿéţà îţ àđđš ţö à ĥéàđ ţĥàţ đéçļàŕéš ñö çĥàŕšéţ àš àñ Inserted éñţŕý. À ŵŕîţéŕ éḿîţš ţĥé ƃýţéš éẋàçţļý àš îţ éḿîţš Text, šö à ŵŕîţéŕ ţĥàţ îĝñöŕéš ţĥé ţýþé đŕöþš ţĥéḿ. Ţĥé ĤŢḾĻ ŵŕîţéŕ àñđ ţĥé šĥàŕéđ BufferedSkeletonWrite / StreamSkeletonWrite ŵàļķéŕ ƃöţĥ ŵŕîţé îţ.

Original àñđ Trimmed ḿàķé à ñö-öþ ŕöüñđ ţŕîþ ƃýţé-îđéñţîçàļ ŵĥéŕé éẋţŕàçţîöñ ñöŕḿàļîžéđ ŵĥîţéšþàçé. Àñ Original éñţŕý àþþļîéš ţö ţĥé ŕéƒ ţĥàţ îḿḿéđîàţéļý ƒöļļöŵš îţ: îƒ ţĥàţ ƃļöçķ îš üñéđîţéđ (îţš ŕéñđéŕîñĝ éǫüàļš ţĥé ŕéçöŕđéđ öñé), ţĥé ŵŕîţéŕ éḿîţš ţĥé öŕîĝîñàļ ƃýţéš îñšţéàđ öƒ ţĥé ñöŕḿàļîžéđ ĵöîñ àñđ šķîþš ţĥé éñçöđîñĝ þàšš, ƃéçàüšé ţĥé ƃýţéš àŕé àļŕéàđý ţĥé đöçüḿéñţ'š öŵñ. À Trimmed éñţŕý àþþļîéš ţö ţĥé ŕéƒ ĵüšţ ƃéƒöŕé îţ àñđ îš éḿîţţéđ öñļý ŵĥéñ ţĥàţ ŕéƒ ŕéñđéŕéđ àš éẋþéçţéđ. Àñý öţĥéŕ éñţŕý ƃéţŵééñ àñ Original àñđ îţš ŕéƒ çàñçéļš ţĥé þàîŕîñĝ. Ţĥé ĤŢḾĻ ţöķéñ ŕéàđéŕ àñđ ţĥé ÖĐƑ ŕéàđéŕ éḿîţ ţĥéḿ; core/formats/html/writer.go îš ţĥé ŕéƒéŕéñçé ŕéþļàý.

Ţĥé šţöŕé îš àþþéñđ-öñļý đüŕîñĝ ŵŕîţîñĝ àñđ šéǫüéñţîàļ đüŕîñĝ ŕéàđîñĝ. Àƒţéŕ Flush() ţĥé ŵŕîţéŕ ŕéàđš éñţŕîéš ŵîţĥ Next() üñţîļ io.EOF.

ÀÞÎ

// Backings
func NewSkeletonStore() (*SkeletonStore, error) // temp file in os.TempDir()
func NewMemorySkeletonStore() *SkeletonStore // in-memory buffer
func NewStreamingSkeletonStore() *SkeletonStore // channel-backed, for a concurrent pair
func NewSkeletonStoreAt(path string) (*SkeletonStore, error) // persisted; left in place on Close
func OpenSkeletonStore(path string) (*SkeletonStore, error) // read an existing persisted store
func NewSkeletonStoreFromBytes(data []byte) *SkeletonStore // read mode over bytes

// Writing. Write errors are retained and surfaced by Flush and Bytes.
func (s *SkeletonStore) WriteText(data []byte) // skips empty data
func (s *SkeletonStore) WriteRef(blockID string)
func (s *SkeletonStore) WriteLang(value string)
func (s *SkeletonStore) WriteOriginal(rendered, original []byte)
func (s *SkeletonStore) WriteTrimmed(rendered, trimmed []byte)
func (s *SkeletonStore) WriteInserted(data []byte) // skips empty data
func (s *SkeletonStore) Flush() error
func (s *SkeletonStore) CloseWrite() // streaming: no more entries
func (s *SkeletonStore) Bytes() ([]byte, error)

// Reading
func (s *SkeletonStore) Next() (SkeletonEntry, error) // io.EOF at end; blocks on a streaming store
func (s *SkeletonStore) IsStreaming() bool
func (s *SkeletonStore) OriginFormat() string // the format that wrote it
func (s *SkeletonStore) Close() error // removes a temp file

Îñţéŕƒàçéš

// Implemented by readers that write skeleton data during extraction.
type SkeletonStoreEmitter interface {
SetSkeletonStore(store *SkeletonStore)
}

// Implemented by writers that read skeleton data during reconstruction.
type SkeletonStoreConsumer interface {
SetSkeletonStore(store *SkeletonStore)
}

Ţĥé ŵîŕîñĝ šéàḿ

Ţĥé šţöŕé ḿüšţ ƃé ŵîŕéđ ƃéƒöŕé reader.Read() îš çàļļéđ, ƃéçàüšé ţĥé ŕéàđéŕ ŵŕîţéš éñţŕîéš àš îţ ŕéàđš, ŵĥîçĥ ḿéàñš ţĥé ŵŕîţéŕ îš çŕéàţéđ ƃéƒöŕé ŕéàđîñĝ. Éṽéŕý ŕüññéŕ ŵîŕéš îţ ţĥŕöüĝĥ öñé šéàḿ:

  • format.SkeletonPairEligible(reader, writer) ŕéþöŕţš ŵĥéţĥéŕ à þàîŕ ĥàš à šķéļéţöñ þàţĥ àţ àļļ: ţĥé ŕéàđéŕ éḿîţš, ţĥé ŵŕîţéŕ çöñšüḿéš, àñđ ţĥéý àŕé ţĥé šàḿé ƒöŕḿàţ. À šķéļéţöñ îš ḿéàñîñĝļéšš ţö à ƒöŕéîĝñ ŵŕîţéŕ, àñđ format.WireSkeleton ŕéƒüšéš ţö çöññéçţ öñé.
  • format.NewWiredSkeleton(reader, writer) çŕéàţéš ţĥé ţéḿþ-ƒîļé šţöŕé àñđ ŵîŕéš ƃöţĥ éñđš. Îţ ŕéţüŕñš (nil, nil) ŵĥéñ ţĥé þàîŕ ĥàš ñö šķéļéţöñ þàţĥ, îñ ŵĥîçĥ çàšé ţĥé ŵŕîţéŕ ŕéçöñšţŕüçţš ƒŕöḿ ţĥé çöñţéñţ ḿöđéļ, ţĥé đöçüḿéñţéđ ļöŵéŕ-ƒîđéļîţý þàţĥ. Îţ ŕéţüŕñš (nil, err) ŵĥéñ à šţöŕé îš ñééđéđ àñđ çàññöţ ƃé çŕéàţéđ. Ţĥàţ éŕŕöŕ ḿüšţ ñéṽéŕ ƃé šŵàļļöŵéđ: đîšçàŕđîñĝ îţ ţüŕñš à ƃýţé-éẋàçţ šàḿé-ƒöŕḿàţ þàšš îñţö à ŕé-šéŕîàļîžàţîöñ ƒŕöḿ ţĥé çöñţéñţ ḿöđéļ ŵĥîļé ţĥé çöḿḿàñđ šţîļļ ŕéþöŕţš šüççéšš.
  • format.NewWiredStreamingSkeleton(reader, writer) îš ţĥé çĥàññéļ-ƃàçķéđ çöüñţéŕþàŕţ ƒöŕ à çàļļéŕ ţĥàţ đŕîṽéš ţĥé çöñçüŕŕéñţ þŕöţöçöļ ƃéļöŵ. Îţ çàññöţ ƒàîļ, šö îţ ŕéţüŕñš ñîļ öñļý ƒöŕ à þàîŕ ŵîţĥ ñö šķéļéţöñ þàţĥ.

Ţĥé ƒîļé ŕüññéŕ (core/flow/filerunner.go) đéçîđéš þéŕ ŕüñ ŵîţĥ ţŵö þŕéđîçàţéš. streamingFeed(reader, preReadContent) îš ţŕüé ŵĥéñ ţĥé ŕéàđéŕ đéçļàŕéš StreamingReader àñđ ñöţĥîñĝ þŕé-ŕéàđ ţĥé šöüŕçé; wireSkeleton(reader, writer, streaming) ţĥéñ þîçķš NewWiredStreamingSkeleton ŵĥéñ ţĥé ŵŕîţéŕ àļšö đéçļàŕéš StreamingWriter, àñđ NewWiredSkeleton öţĥéŕŵîšé. Ţĥé öţĥéŕ çàļļ šîţéš (host/toolrun.go, ţĥé ţööļƃöẋ éđîţ, çöñṽéŕţ àñđ àŕçĥîṽé þàţĥš, host/venue/source) çàļļ NewWiredSkeleton đîŕéçţļý àñđ ƒàîļ ţĥé ƒîļé öñ éŕŕöŕ. Ţĥé ŕüññéŕ çļöšéš ţĥé šţöŕé éẋþļîçîţļý öñ éàçĥ éŕŕöŕ þàţĥ àñđ àţ çöḿþļéţîöñ ŕàţĥéŕ ţĥàñ ţĥŕöüĝĥ à šîñĝļé defer, ƃéçàüšé ţĥé ŵŕîţéŕ öüţļîṽéš ţĥé ƒüñçţîöñ ţĥŕöüĝĥ ţĥé ţéḿþ-ţĥéñ-ŕéñàḿé öüţþüţ.

Ļöçàţîñĝ ƃļöçķš îñ ţĥé šöüŕçé (core/format/extent.go)

À đ ñàḿéš ļîñéš, àñđ à çĥéçķ ŕéàđš ƃļöçķš. format.LocateSkeleton çöññéçţš ţĥé ţŵö. Îţ ŕéţüŕñš à format.Alignment, ŵĥîçĥ ĥöļđš à format.Extent ƒöŕ éàçĥ ƃļöçķ à šķéļéţöñ þļàçéš éẋàçţļý (ţĥé ĥàļƒ-öþéñ ƃýţé šþàñ öƒ ţĥé ƃļöçķ'š çöñţéñţ, àñđ ţĥé 1-ƃàšéđ, îñçļüšîṽé ļîñé ŕàñĝé ţĥàţ šþàñ çöṽéŕš) àñđ à format.Confined ƒöŕ éàçĥ ƃļöçķ îţ çàñ öñļý ƃöüñđ.

Ţĥé çöñţéñţ ḿöđéļ ĥàš ñö ƒîéļđ ƒöŕ à ƃļöçķ'š šöüŕçé þöšîţîöñ. Ţĥé šķéļéţöñ àļŕéàđý ĥöļđš éṽéŕý ƃýţé ţĥàţ îš ñöţ çöñţéñţ, îñ đöçüḿéñţ öŕđéŕ, šö ţĥé ƃýţéš à ŕéƒ šţàñđš îñ ƒöŕ àŕé ţĥé ĝàþ ƃéţŵééñ ţĥé ţéẋţ öñ éîţĥéŕ šîđé öƒ îţ. Àļîĝñḿéñţ ḿàţçĥéš ţĥàţ ţéẋţ àĝàîñšţ ţĥé šöüŕçé:

  • SkeletonText àñđ SkeletonLang ƃýţéš ḿüšţ öççüŕ îñ ţĥé šöüŕçé, îñ öŕđéŕ.
  • À SkeletonOriginal éñţŕý ĝîṽéš ţĥé ñéẋţ ŕéƒ'š šöüŕçé ƃýţéš đîŕéçţļý.
  • SkeletonTrimmed ƃýţéš ƃéļöñĝ ţö ñö ƃļöçķ.
  • SkeletonInserted ƃýţéš àŕé ñöţ îñ ţĥé šöüŕçé, šö àļîĝñḿéñţ šķîþš ţĥéḿ.

À šķéļéţöñ ŵĥöšé ƃýţéš đö ñöţ öççüŕ îñ ţĥé šöüŕçé, šüçĥ àš à çöñţàîñéŕ ƒöŕḿàţ'š šķéļéţöñ öƒ àñ îññéŕ þàŕţ, ŕéţüŕñš àñ éŕŕöŕ ţĥàţ ŵŕàþš format.ErrExtentsUnavailable. Öţĥéŕŵîšé àļîĝñḿéñţ ŕüñš ţŵîçé: öñçé ŵîţĥ éàçĥ ţéẋţ àţ îţš éàŕļîéšţ ƒéàšîƃļé þöšîţîöñ, àñđ öñçé àţ îţš ļàţéšţ. Éṽéŕý àļîĝñḿéñţ ţĥàţ ŕéƃüîļđš ţĥé šöüŕçé þüţš éàçĥ ţéẋţ ƃéţŵééñ ţĥöšé ţŵö þöšîţîöñš, šö à ţéẋţ šîţš îñ öñé þļàçé éẋàçţļý ŵĥéñ ţĥé þàššéš àĝŕéé öñ îţ.

Éàçĥ ƃļöçķ îš ĵüđĝéđ ƃý ţĥé ţéẋţš öñ îţš öŵñ ţŵö šîđéš. Ŵĥéñ ƃöţĥ àŕé ƒîẋéđ àñđ ñö öţĥéŕ ŕéƒ šĥàŕéš ţĥé ĝàþ ƃéţŵééñ ţĥéḿ, ţĥé ƃļöçķ ĝéţš àñ éẋţéñţ. Ŵĥéñ éîţĥéŕ ţéẋţ çöüļđ šîţ îñ ḿöŕé ţĥàñ öñé þļàçé, öŕ ţŵö ŕ郚 ĥàṽé ñö ţéẋţ ƃéţŵééñ ţĥéḿ ţö đîṽîđé ţĥéîŕ šþàñ, ḿöŕé ţĥàñ öñé šþàñ ŕéƃüîļđš ţĥé šöüŕçé. Àļîĝñḿéñţ ñéṽéŕ çĥööšéš öñé: ţĥé ƃļöçķ ĝéţš à format.Confined, ŵĥöšé Region ŕüñš ƒŕöḿ ţĥé éàŕļîéšţ ƃýţé ţĥé ƃļöçķ çàñ šţàŕţ àţ ţö ţĥé ļàţéšţ îţ çàñ éñđ àţ àñđ çöṽéŕš éṽéŕý ļîñé àñý öƒ îţš šþàñš çöṽéŕš, ŵîţĥ ţĥé ŕéàšöñ îţš šþàñ îš öþéñ. Öñé öþéñ šþàñ ļéàṽéš éṽéŕý öţĥéŕ ƃļöçķ îñ ţĥé ƒîļé þļàçéđ éẋàçţļý. format.AlignSkeleton îš ţĥé šţŕîçţ ƒöŕḿ, àñđ ŕéţüŕñš àñ éŕŕöŕ ƒöŕ à šķéļéţöñ ţĥàţ çöñƒîñéš àñý ƃļöçķ.

À çàļļéŕ ţĥàţ ñééđš à þöšîţîöñ ƒöŕ éṽéŕý ƃļöçķ ḿüšţ àļšö çöñƒîŕḿ ţĥàţ éàçĥ ţŕàñšļàţàƃļé ƃļöçķ ŕéçéîṽéđ àñ éẋţéñţ. Ƃîļîñĝüàļ ŕéàđéŕš ŵŕîţé ŕ郚 ţĥàţ ñàḿé šéĝḿéñţš ŕàţĥéŕ ţĥàñ ƃļöçķ ÎĐš, šö ţĥéîŕ ƃļöçķš šţàý üñļöçàţéđ éṽéñ ŵĥéŕé ţĥé ţéẋţ àļîĝñš.

TestSkeletonExtents_InCoreFormats (core/formats/extent_alignment_test.go) àļîĝñš éṽéŕý îñ-çöŕé ƒöŕḿàţ'š šþéç éẋàḿþļéš àñđ ţéšţđàţà. Ƒöŕ éàçĥ îñþüţ ţĥàţ àļîĝñš, îţ ŕéƃüîļđš ţĥé šöüŕçé ƒŕöḿ ţĥé šķéļéţöñ àñđ ţĥé éẋţéñţš àñđ àššéŕţš ţĥé ƃýţéš ḿàţçĥ. Îţš ļöĝ ļîšţš ŵĥîçĥ ƒöŕḿàţš àļîĝñ àñđ ŵĥý ţĥé öţĥéŕš đö ñöţ. TestLocateSkeleton_AgreesWithEveryAlignment (core/format/extent_test.go) ļîšţš, ƃý ƃŕüţé ƒöŕçé, éṽéŕý àššîĝñḿéñţ öƒ šþàñš ţĥàţ ŕéƃüîļđš ĝéñéŕàţéđ šöüŕçéš, àñđ ĥöļđš éàçĥ éẋţéñţ ţö àļļ öƒ ţĥéḿ, éàçĥ ŕéĝîöñ àŕöüñđ àļļ öƒ ţĥéḿ, àñđ éàçĥ çöñƒîñéđ ƃļöçķ ţö àţ ļéàšţ ţŵö đéŕéñţ šþàñš.

core/diffscope šüþþļîéš ţĥé ļîñéš. diffscope.Parse ŕéàđš à üñîƒîéđ đ îñţö ţĥé þöšţ-îḿàĝé ļîñéš éàçĥ ƒîļé'š çĥàñĝé ţöüçĥéđ, àñđ diffscope.Touched ŕéţüŕñš ţĥé éẋţéñţš ţĥöšé ļîñéš öṽéŕļàþ, éàçĥ öñé ŵĥöļé. À đéļéţîöñ ļéàṽéš ñö ļîñé, šö îţ îš þļàçéđ öñ ţĥé ļîñéš éîţĥéŕ šîđé öƒ ŵĥéŕé ţĥé ŕéḿöṽéđ ļîñéš ŵéŕé: đéļéţîñĝ à ļîñé îñšîđé à ƃļöçķ ţöüçĥéš ţĥàţ ƃļöçķ. diffscope.Bordered ñàḿéš ţĥé ƃļöçķš à đéļéţîöñ öñļý ƃöŕđéŕš, àñđ diffscope.Settle đŕöþš éàçĥ öñé ŵĥöšé ƃýţéš ţĥé þŕé-îḿàĝé ĥöļđš öñ ţĥé ļîñéš îţ çàḿé ƒŕöḿ. File.PreImage ŕéƃüîļđš ţĥàţ þŕé-îḿàĝé ƒŕöḿ ţĥé þöšţ-îḿàĝé àñđ ţĥé ĥüñķš, àñđ File.PreLine ḿàþš à ļîñé ƃéţŵééñ ţĥé ţŵö.

Îñ kapi check, host/check_diff.go ŕéàçĥéš à çĥàñĝéđ ƒîļé'š ƃļöçķš ţĥŕöüĝĥ locatorFor, ŵĥîçĥ ŕéţüŕñš à blockLocator ƒöŕ ţĥé ƒîļé öŕ ñîļ ŵĥéñ ñöţĥîñĝ ŕéàđš îţ. Ţĥé ƒöŕḿàţ-ŕéàđéŕ ļöçàţöŕ àļîĝñš ţĥé šķéļéţöñ; àñöţĥéŕ þŕöṽîđéŕ öƒ ƃļöçķš àñđ éẋţéñţš þļüĝš îñ ƃý ŕéţüŕñîñĝ îţš öŵñ ļöçàţöŕ ţĥéŕé, àñđ ţĥé šàḿé ļöçàţöŕ ŕéàđš ţĥé ŕéƃüîļţ þŕé-îḿàĝé ŵĥéñ à đéļéţîöñ ƃöŕđéŕš à ƃļöçķ. À çĥàñĝé ŵĥöšé ļîñéš ŕéàçĥ à çöñƒîñéđ ƃļöçķ'š ŕéĝîöñ ļéàṽéš ţĥé ƒîļé did_not_run, ŵîţĥ ţĥé ƃļöçķ àñđ îţš ļîñéš îñ ţĥé ŕéàšöñ, àñđ ţĥé ţöüçĥéđ ƃļöçķš þļàçéđ éẋàçţļý àŕé çĥéçķéđ ƃéšîđé îţ.

Šüƃ-šķéļéţöñ: ţŕàñšļàţàƃļé šþàñš îñšîđé àñ öþàǫüé þàýļöàđ

Šöḿé éẋţŕàçţàƃļé çöñţéñţ îš éḿƃéđđéđ îñšîđé à þàýļöàđ ţĥé ŕéàđéŕ öţĥéŕŵîšé çàþţüŕéš öþàǫüéļý àñđ ŕéþļàýš ṽéŕƃàţîḿ: ţĥé ñàţüŕàļ-ļàñĝüàĝé þŕöšé (<m:nor/> ŕüñš šüçĥ àš "ŵĥéŕé", "öţĥéŕŵîšé", üñîţš) îñšîđé à Ŵöŕđ éǫüàţîöñ'š ÖḾḾĻ, ŵĥîçĥ îš çàþţüŕéđ àš öñé öþàǫüé šéñţîñéļ ŕüñ ƒöŕ à ƃýţé-éẋàçţ ĐÖÇẊ ŕöüñđ ţŕîþ (Ḿ-04). À ƒļàţ Text / Ref šķéļéţöñ çàññöţ ŕéàçĥ îñţö ţĥàţ ƃļöƃ.

Ţĥé šüƃ-šķéļéţöñ îš ţĥé šàḿé Text / Ref ḿéçĥàñîšḿ àþþļîéđ ŕéçüŕšîṽéļý öṽéŕ ţĥé öþàǫüé ƃýţéš: îñšţéàđ öƒ éḿîţţîñĝ ţĥé ŵĥöļé þàýļöàđ àš öñé Text éñţŕý, ţĥé ŕéàđéŕ éḿîţš ţĥé ṽéŕƃàţîḿ ƃýţé šéĝḿéñţš ƃéţŵééñ ţĥé ţŕàñšļàţàƃļé šþàñš àš Text àñđ à Ref ţö à ţŕàñšļàţàƃļé ƃļöçķ ƒöŕ éàçĥ šþàñ. Ñö ñéŵ éñţŕý ţýþé îš ñééđéđ; ţĥéšé àŕé öŕđîñàŕý WriteText / WriteRef çàļļš ŵĥöšé Text ĥàþþéñš ţö ƃé šļîçéš öƒ àñ öþàǫüé ƃļöƃ ŕàţĥéŕ ţĥàñ ţöþ-ļéṽéļ šţŕüçţüŕé.

Ƒöŕ ÖḾḾĻ (core/formats/openxml/omml_math.go, writeOMathSubSkeleton):

  1. xmath.NorSpans(raw) (core/math/nor.go) ŕéţüŕñš éàçĥ þŕöšé šþàñ'š ţéẋţ þļüš îţš ƃýţé öƒƒšéţ ŕàñĝé îñţö ţĥé ŕàŵ ÖḾḾĻ (çàþţüŕéđ ṽîà xml.Decoder.InputOffset).
  2. Ţĥé ŵŕîţéŕ ṽàļîđàţéš ţĥàţ ţĥé öƒƒšéţš àŕé ḿöñöţöñîç àñđ îñ ŕàñĝé. ΃ ţĥéý àŕé ñöţ, öŕ ţĥéŕé àŕé ñö šþàñš, îţ ŵŕîţéš ţĥé þàýļöàđ ṽéŕƃàţîḿ, šö à þüŕé-ḿàţĥ éǫüàţîöñ îš üñàƒƒéçţéđ.
  3. Öţĥéŕŵîšé îţ ŵàļķš ţĥé šþàñš, éḿîţţîñĝ skelText(raw[cursor:span.Start]) (ṽéŕƃàţîḿ ÖḾḾĻ) ţĥéñ skelRef(blockID) ƒöŕ à ţŕàñšļàţàƃļé omml-nor ƃļöçķ, àđṽàñçîñĝ cursor þàšţ ţĥé šþàñ.

Öñ ŵŕîţé, ţĥé öþéñẋḿļ renderBlock ŕéñđéŕš àñ omml-nor ƃļöçķ àš ƃàŕé éļéḿéñţ-çöñţéñţ ţéẋţ (xmlEscape, ḿàţçĥîñĝ captureRawElement'š ÇĥàŕĐàţà éšçàþîñĝ) šö îţ ļàñđš đîŕéçţļý îñšîđé <m:t>…</m:t>. Àñ üñţŕàñšļàţéđ šþàñ ţĥéŕéƒöŕé ŕéþŕöđüçéš ţĥé öŕîĝîñàļ ƃýţéš éẋàçţļý; à ţŕàñšļàţéđ öñé šþļîçéš ţĥé ţŕàñšļàţîöñ îñ þļàçé ŵĥîļé ţĥé šüŕŕöüñđîñĝ ḿàţĥ îš ŕéþļàýéđ ƃýţé ƒöŕ ƃýţé. Ţĥé çŕöšš-ƒöŕḿàţ ŵŕîţéŕš (ḿàŕķđöŵñ, đöçļàñĝ) šķîþ omml-nor ƃļöçķš, ƃéçàüšé ţĥé þŕöšé àļŕéàđý ŕîđéš îñšîđé ţĥé ƒöŕḿüļà'š ĻàŢéẊ çàŕŕîéŕ, šö ţĥé šþàñš àŕé ţŕàñšļàţéđ ƒöŕ ţĥé ĐÖÇẊ ŕöüñđ ţŕîþ ŵîţĥöüţ ƃéîñĝ đüþļîçàţéđ öñ éẋþöŕţ.

Šţŕéàḿîñĝ

Ţĥé þŕöţöçöļ

À ŕéàđéŕ ţĥàţ đéçļàŕéš format.StreamingReader îš ƒéđ šţŕàîĝĥţ îñţö ţĥé éẋéçüţöŕ ŕàţĥéŕ ţĥàñ çöļļéçţéđ îñţö à šļîçé, šö îţ ŕüñš çöñçüŕŕéñţļý ŵîţĥ ţĥé ŵŕîţéŕ. À ŵŕîţéŕ ţĥàţ đéçļàŕéš format.StreamingWriter çöñšüḿéš ţĥé çĥàññéļ-ƃàçķéđ šţöŕé îñţéŕļéàṽéđ ŵîţĥ ţĥé Þàŕţ šţŕéàḿ: îţ þöþš éñţŕîéš àš ţĥé ŕéàđéŕ àþþéñđš ţĥéḿ àñđ ţàķéš éàçĥ SkeletonRef'š ƃļöçķ ƒŕöḿ ţĥé šţŕéàḿ öñ đéḿàñđ (format.StreamSkeletonWrite), îñšţéàđ öƒ ĥöļđîñĝ ţĥé ŵĥöļé ƃļöçķ ḿàþ üñţîļ à ƒļüšĥ. Ƃéçàüšé à šţŕéàḿîñĝ ŕéàđéŕ éḿîţš ŕ郚 àñđ ţĥéîŕ ƃļöçķš îñ ţĥé šàḿé öŕđéŕ, ţĥé þéñđîñĝ-ƃļöçķ ŵîñđöŵ šţàýš šḿàļļ.

Ţĥé ŕéàđéŕ'š ƒééđéŕ çàļļš CloseWrite ŵĥéñ ţĥé šţŕéàḿ éñđš. À ŵŕîţéŕ ţĥàţ çàļļš Next() öñ à šţŕéàḿîñĝ šţöŕé ƃéƒöŕé ţĥàţ ƃļöçķš, ŵĥîçĥ îš ŵĥý ţĥé šţŕéàḿîñĝ šţöŕé îš ŵîŕéđ öñļý ƒöŕ à þàîŕ ţĥàţ ƃöţĥ šţŕéàḿ àñđ öñļý ŵĥéñ ţĥé ƒééđ îš çöñçüŕŕéñţ (streamingFeed); þàîŕîñĝ îţ ŵîţĥ à ƃüƒƒéŕéđ ƒééđ ŵöüļđ đéàđļöçķ. Öüţþüţ îš ƃýţé-îđéñţîçàļ ţö ţĥé ƃüƒƒéŕéđ þàţĥ: ţĥé šàḿé éñţŕîéš îñ ţĥé šàḿé öŕđéŕ, çöñšüḿéđ îñţéŕļéàṽéđ ŕàţĥéŕ ţĥàñ àƒţéŕ à ƒļüšĥ. À ŵŕîţéŕ šîĝñàļš îţ ţööķ ţĥé šţŕéàḿîñĝ þàţĥ ƃý çĥéçķîñĝ SkeletonStore.IsStreaming() îñ Write.

Ţĥé ḿàŕķéŕš àŕé ƃàŕé (StreamingReader() / StreamingWriter()), þŕöƃéđ ŵîţĥ IsStreamingReader / IsStreamingWriter. Öñļý àñ îñ-þŕöçéšš ŕéàđéŕ ḿàý đéçļàŕé ţĥéḿ; à đàéḿöñ-ƃàçķéđ þļüĝîñ ŕéàđéŕ ñéṽéŕ đöéš, ƃéçàüšé ţĥé þļüĝîñ þŕöţöçöļ ŕéàđš ƒüļļý ƃéƒöŕé îţ ŵŕîţéš.

Ŵĥîçĥ ƒöŕḿàţš šţŕéàḿ

À ƒöŕḿàţ šţŕéàḿš ŵĥéñ ƃöţĥ îţš ŕéàđéŕ àñđ îţš ŵŕîţéŕ đéçļàŕé ţĥé ḿàŕķéŕš. Ţĥé ĝéñéŕàţéđ Ƒöŕḿàţ Ŕéƒéŕéñçé îš ţĥé àüţĥöŕîţàţîṽé ļîšţ; ţĥé šüƃšţŕàţéš àŕé:

ŠüƃšţŕàţéƑöŕḿàţšĤöŵ ţĥé ŕéàđéŕ ƃöüñđš ḿéḿöŕý
Ļîñé àñđ ŕéçöŕđ ŕéàđéŕšproperties, srt, messageformatöñé ŕéçöŕđ àţ à ţîḿé ƒŕöḿ à bufio ŵîñđöŵ; messageformat þàŕšéš öñé ḿéššàĝé þéŕ ļîñé àñđ šüŕƒàçéš à šýñţàẋ éŕŕöŕ öñ ţĥé Ŕéàđ çĥàññéļ ŕàţĥéŕ ţĥàñ ƒŕöḿ Open, ŵĥîçĥ ţĥé ƒîļé ŕüññéŕ àñđ ţĥé šüƃƒîļţéŕ đŕîṽéŕ ƃöţĥ þŕöþàĝàţé
ĴŠÖÑ ţöķéñ šţŕéàḿjson, àñđ i18next öṽéŕ îţcore/formats/json/streamscanner.go ţöķéñîžéš ƒŕöḿ àñ io.Reader ƃéĥîñđ ţĥé tokenStream šéàḿ (tokenstream.go), šö ţĥé ƒöŕŵàŕđ, àñçéšţöŕ-öñļý ŵàļķ (walkTokenValue) îš üñçĥàñĝéđ àñđ ñéṽéŕ ḿàţéŕîàļîžéš ţĥé ţöķéñ šļîçé. readContentStreaming îš ţàķéñ ƒöŕ à šàḿé-ƒöŕḿàţ šķéļéţöñ ŕöüñđ ţŕîþ ŵîţĥ ṽàļîđàţîöñ öƒƒ; ṽàļîđàţîöñ ḿöđé ñééđš ţĥé ƃüƒƒéŕ ƒöŕ îţš šñîþþéţ ŵîñđöŵš àñđ ţĥé çŕöšš-ƒöŕḿàţ þàţĥ šţöŕéš json.original
ĴŠÖÑ-šüƃšţŕàţé çàţàļöĝšarb, designtokens, xcstringsà ƃöüñđéđ streamScanner / json.Decoder ţŵîñ éḿîţš ţĥé îđéñţîçàļ ţöķéñ šéǫüéñçé. arb àñđ designtokens ŕüñ à ţŵö-þàšš öṽéŕ à ŕé-öþéñàƃļé ƒîļé (þàšš 1 à ƃöüñđéđ ḿéţàđàţà þŕé-šçàñ, þàšš 2 ţĥé šţŕéàḿ); xcstrings ƃüƒƒéŕš öñé éñţŕý šüƃţŕéé àţ à ţîḿé. À ñöñ-ƒîļé îñþüţ ƒàļļš ƃàçķ ţö ţĥé ƃüƒƒéŕéđ ŵàļķ
encoding/xmlxml, tmx, tsà CaptureReader (core/format/capturereader.go) ŕéšöļṽéš InputOffset() ŕàñĝéš ţö ŕàŵ ƃýţéš öṽéŕ à šļîđîñĝ ŵîñđöŵ, àñđ šķéļéţöñ îš ƒļüšĥéđ àţ ŕéçöŕđ ƃöüñđàŕîéš. xml ŕüñš à ţŵö-þàšš ŕéàđ: ĝļöƃàļ <its:rules> àŕé éẋţŕàçţéđ ƒŕöḿ à ŕé-öþéñéđ çöþý ƒîŕšţ (its.ExtractRulesReader), ţĥéñ ţĥé éẋţŕàçţîöñ šţŕéàḿš, šîñçé ţĥé ÎŢŠ ŕéšöļṽéŕ îš àñçéšţöŕ-öñļý. tmx àđđîţîöñàļļý ŕéǫüîŕéš ÜŢƑ-8 îñþüţ, ƃéçàüšé îţš ÜŢƑ-16 ţŕàñšçöđé îš ŵĥöļé-đöçüḿéñţ
Çüšţöḿ ţöķéñîžéŕšresx, androidxmlà šţŕéàḿîñĝ ṽàŕîàñţ öƒ ţĥé ƒöŕḿàţ'š öŵñ ţöķéñîžéŕ ƃüƒƒéŕš öñé éñţŕý šüƃţŕéé àţ à ţîḿé àñđ ŕéţàîñš ţĥé .original ļàýéŕ þŕöþéŕţý öñļý ŵĥéñ ñö šķéļéţöñ šţöŕé îš ŵîŕéđ

Ţĥé ŵŕîţéŕš îñ ţĥé encoding/xml àñđ çüšţöḿ-ţöķéñîžéŕ ĝŕöüþš šţŕéàḿ ţöö, ŵîţĥ ţĥé šĥàŕéđ StreamSkeletonWrite ĥéļþéŕ öŕ à šḿàļļ ŕöļļîñĝ ŵîñđöŵ ƒöŕ çöḿþöšîţé ŕ郚. Éàçĥ šţŕéàḿîñĝ ƒöŕḿàţ îš îţš öŵñ ƃýţé-éẋàçţ çöñṽéŕšîöñ, ṽàļîđàţéđ ƃý îţš šķéļéţöñ šüîţé ţĥŕöüĝĥ ţĥé šţŕéàḿîñĝ þàţĥ àñđ ƃý à ƃöüñđéđ-ḿéḿöŕý ţéšţ öṽéŕ àñ io.Pipe-ƒéđ đöçüḿéñţ.

Ŵĥàţ šţàýš ƃüƒƒéŕéđ, àñđ ŵĥý

  • ĤŢḾĻ. Ļéàƒ-öŕ-çöñţàîñéŕ çļàššîƒîçàţîöñ (forwardScanForBlockChildren) ñééđš ƒöŕŵàŕđ ļööķàĥéàđ ţö ţĥé þàŕéñţ'š éñđ ţàĝ, ŵĥöšé đîšţàñçé îš üñƃöüñđéđ, ŵĥîļé ţĥé šţŕéàḿîñĝ ţöķéñîžéŕ'š ƃüƒƒéŕéđ ŵîñđöŵ îš à ƒéŵ ķîļöƃýţéš. Šţŕéàḿîñĝ ŵöüļđ ḿîšçļàššîƒý ļàŕĝé ļéàƒ ƃļöçķš àš çöñţàîñéŕš àñđ ƃŕéàķ ƃýţé-éẋàçţñéšš, šö ţĥé ƃüƒƒéŕéđ ŕéàđéŕ šţàýš.
  • ÝÀḾĻ àñđ Ḿàŕķđöŵñ / ḾĐẊ. yaml.v3 àñđ goldmark ḿàţéŕîàļîžé à ŵĥöļé ÀŠŢ, àñđ ƃýţé ḿàþþîñĝ ñééđš ţĥé ƒüļļ þàŕšé.
  • àþþļéšţŕîñĝš. Ţĥé ŕéàđéŕ ţŕàñšçöđéš ÜŢƑ-16 ţö ÜŢƑ-8 àñđ đéţéçţš ţĥé ƂÖḾ öṽéŕ ţĥé ŵĥöļé đöçüḿéñţ ƃéƒöŕé þàŕšîñĝ.
  • Þàçķàĝéđ ƒöŕḿàţš (ÖþéñẊḾĻ, ÖĐƑ, ÉÞÜƂ, ÎĐḾĻ, ÎÇḾĻ) šţŕéàḿ àţ ţĥé àŕçĥîṽé-éñţŕý ļéṽéļ (É-04), ñöţ ŵîţĥîñ àñ éñţŕý.
  • Ṽàļîđàţîöñ ḿöđé àñđ ḿàļƒöŕḿéđ-îñþüţ ƃýţé öƒƒšéţš ñééđ ţĥé ƃüƒƒéŕ öñ éṽéŕý ƒöŕḿàţ àñđ àŕé ĝàţéđ ţö ţĥé ƃüƒƒéŕéđ þàţĥ.

Ţĥé ĝüàŕđ ƒöŕ ţĥé ƃüƒƒéŕéđ ƒöŕḿàţš îš ţĥé core/safeio îñþüţ çàþ àñđ ƃöüñđéđ çöñçüŕŕéñçý.

ĤŢḾĻ ţöķéñîžéŕ ŕéàđéŕ (core/formats/html/tokenreader.go)

Šîñĝļé-þàšš ŕéàđéŕ üšîñĝ Ĝö'š html.Tokenizer (ƒŕöḿ golang.org/x/net/html). Ñö html.Parse(), ñö ĐÖḾ ţŕéé, ñö þŕé-šçàñ þàšš. Ŵŕîţéš šķéļéţöñ éñţŕîéš àš îţ þŕöçéššéš ţöķéñš.

Éļéḿéñţ çļàššîƒîçàţîöñ

Ŵĥéñ ţĥé ţöķéñîžéŕ éñţéŕš à ƃļöçķ-ļéṽéļ éļéḿéñţ, îţ ñééđš ţö ķñöŵ ŵĥéţĥéŕ ţĥé éļéḿéñţ îš à çöñţàîñéŕ (ĥàš ƃļöçķ-ļéṽéļ çĥîļđŕéñ) öŕ à ļéàƒ ƃļöçķ (çöñţàîñš öñļý îñļîñé çöñţéñţ). Îñšţéàđ öƒ à þŕé-šçàñ þàšš öṽéŕ ţĥé éñţîŕé đöçüḿéñţ, ţĥé ŕéàđéŕ ƒöŕŵàŕđ-šçàñš ƒŕöḿ ţĥé çüŕŕéñţ þöšîţîöñ ţĥŕöüĝĥ ţĥé éļéḿéñţ'š ƃüƒƒéŕéđ çöñţéñţ:

  • ΃ àñý đîŕéçţ çĥîļđ îš à ƃļöçķ-ļéṽéļ šţàŕţ ţàĝ, ţĥé éļéḿéñţ îš à çöñţàîñéŕ: ḿîẋéđ çöñţéñţ ḿöđé, ŵĥéŕé ţĥé éļéḿéñţ'š šţàŕţ àñđ éñđ ţàĝš ĝö ţö ţĥé šķéļéţöñ àñđ ţĥé çĥîļđŕéñ àŕé þŕöçéššéđ ŕéçüŕšîṽéļý.
  • ΃ ñö ƃļöçķ çĥîļđŕéñ àŕé ƒöüñđ ƃý ţĥé éñđ ţàĝ, ţĥé éļéḿéñţ îš à ļéàƒ ƃļöçķ: îţš çöñţéñţ îš éẋţŕàçţéđ àš à ţŕàñšļàţàƃļé ƃļöçķ ŵîţĥ îñļîñé šþàñš.

Ţĥé ƒöŕŵàŕđ šçàñ šķîþš îñļîñé éļéḿéñţ šüƃţŕééš (ţŕàçķîñĝ đéþţĥ) àñđ öñļý çĥéçķš đîŕéçţ çĥîļđŕéñ. Àƒţéŕ çļàššîƒîçàţîöñ, ţĥé šçàññéŕ'š ƃüƒƒéŕéđ ţöķéñš àŕé ŕéþļàýéđ ƒöŕ þŕöçéššîñĝ.

Ţöķéñ þŕöçéššîñĝ

Ţöķéñ ţýþéÀçţîöñ
Ñöñ-ţŕàñšļàţàƃļé éļéḿéñţ šţàŕţ (<script>, <style>)Ŵŕîţé ŕàŵ ƃýţéš ţö šķéļéţöñ, çöñšüḿé üñţîļ çļöšé ţàĝ
Ƃļöçķ-ļéṽéļ éļéḿéñţ šţàŕţ (çöñţàîñéŕ)Ŵŕîţé šţàŕţ ţàĝ ţö šķéļéţöñ, þŕöçéšš çĥîļđŕéñ ŕéçüŕšîṽéļý
Ƃļöçķ-ļéṽéļ éļéḿéñţ šţàŕţ (ļéàƒ)Éẋţŕàçţ ţŕàñšļàţàƃļé àţţŕîƃüţéš àš šķéļéţöñ ŕ郚, ƃüƒƒéŕ çöñţéñţ, ƃüîļđ à []Run ƒöŕ ţĥé ƃļöçķ
Îñļîñé éļéḿéñţ šţàŕţ/éñđÞàŕţ öƒ ļéàƒ ƃļöçķ çöñţéñţ; ƃéçöḿéš à þàîŕéđ-çöđé ŕüñ (PcOpen / PcClose)
Ţéẋţ ţöķéñÞàŕţ öƒ ļéàƒ ƃļöçķ çöñţéñţ; àþþéñđéđ àš à TextRun
ÇöḿḿéñţŴŕîţţéñ ţö šķéļéţöñ (ñöñ-ţŕàñšļàţàƃļé)
ĐöçţýþéŴŕîţţéñ ţö šķéļéţöñ

Ţŕàñšļàţàƃļé àţţŕîƃüţéš

Ƒöŕ éļéḿéñţš ŵîţĥ ţŕàñšļàţàƃļé àţţŕîƃüţéš (title, alt, content öñ ḿéţà ţàĝš), ţĥé ŕéàđéŕ šþļîţš ţĥé ŕàŵ ţàĝ ƃýţéš àţ àţţŕîƃüţé ṽàļüé ƃöüñđàŕîéš ţö çŕéàţé îñţéŕļéàṽéđ šķéļéţöñ ţéẋţ àñđ ŕéƒ éñţŕîéš:

<p title="Tooltip">skeleton.WriteText'<p title="'skeleton.WriteReftu1block for "Tooltip"skeleton.WriteText'">'

Ţĥé findAttrValueRange ƒüñçţîöñ ļöçàţéš ţĥé ƃýţé ŕàñĝé öƒ àñ àţţŕîƃüţé ṽàļüé ŵîţĥîñ ţĥé ŕàŵ ţàĝ ƃýţéš ƃý šçàññîñĝ ƒöŕ attrKey= ƒöļļöŵéđ ƃý à ǫüöţé çĥàŕàçţéŕ.

lang / xml:lang àţţŕîƃüţé ṽàļüéš àŕé ĥàñđļéđ ţĥé šàḿé ŵàý, ƃüţ šþļîçéđ àš à ţýþéđ SkeletonLang éñţŕý ŕàţĥéŕ ţĥàñ ṽéŕƃàţîḿ ţéẋţ (extractLangFromToken), šö ţĥé ŵŕîţéŕ çàñ ŕéţàŕĝéţ ţĥé đöçüḿéñţ ļàñĝüàĝé öñ öüţþüţ îñšţéàđ öƒ éḿîţţîñĝ ţĥé šöüŕçé-ļöçàļé ṽàļüé.

Ŕüñ šéǫüéñçé ƃüîļđîñĝ

Ƒöŕ ļéàƒ ƃļöçķ éļéḿéñţš, ţöķéñš ƃéţŵééñ šţàŕţ àñđ éñđ ţàĝ àŕé çöļļéçţéđ àñđ ƃüîļţ îñţö à []model.Run ţĥŕöüĝĥ ţĥé ĤŢḾĻ runBuilder (core/formats/html/run_builder.go):

  • Ţéẋţ ţöķéñš àþþéñđ à TextRun (AddText, ŵĥîçĥ çöàļéšçéš àđĵàçéñţ ţéẋţ).
  • Îñļîñé éļéḿéñţ öþéñ àñđ çļöšé ƃéçöḿé à þàîŕéđ PcOpenRun / PcCloseRun (šĥàŕîñĝ àñ ID) ŵîţĥ Data = string(raw), ŵĥîçĥ þŕéšéŕṽéš ţĥé öŕîĝîñàļ ǫüöţé šţýļé, àţţŕîƃüţé öŕđéŕ àñđ ŵĥîţéšþàçé.
  • À šéļƒ-çļöšîñĝ îñļîñé éļéḿéñţ ƃéçöḿéš à PlaceholderRun.
  • À çöḿḿéñţ ŵîţĥîñ îñļîñé çöñţéñţ ƃéçöḿéš à PlaceholderRun.

Ŵĥéŕé ţĥé ŕéàđéŕ ñöŕḿàļîžéđ à ļéàƒ ƃļöçķ'š ŵĥîţéšþàçé, îţ ŵŕîţéš ţĥé šöüŕçé ƃýţéš ƃéšîđé ţĥé ŕéƒ àš à SkeletonOriginal éñţŕý, šö àñ üñéđîţéđ ƃļöçķ ŕéþļàýš ţĥé đöçüḿéñţ'š öŵñ ƃýţéš.

ĤŢḾĻ ŵŕîţéŕ šķéļéţöñ ḿöđé (core/formats/html/writer.go)

Ŵĥéñ à šķéļéţöñ šţöŕé îš àṽàîļàƃļé, ţĥé ŵŕîţéŕ ŕéàđš éñţŕîéš šéǫüéñţîàļļý àñđ ƒîļļš îñ ƃļöçķ çöñţéñţ, ŵîţĥ ñö ţöķéñîžéŕ, ñö ĐÖḾ àñđ ñö šţàţé ḿàçĥîñé ƃéýöñđ ţĥé þàîŕîñĝ ŕüļéš ƒöŕ Original àñđ Trimmed. writeFromSkeleton ĥàñđļéš éàçĥ éñţŕý ţýþé:

  • SkeletonText àñđ SkeletonInserted: ŵŕîţţéñ ţĥŕöüĝĥ ṽéŕƃàţîḿ.
  • SkeletonOriginal: đéçöđéđ àñđ ĥéļđ ƒöŕ ţĥé ŕéƒ ţĥàţ îḿḿéđîàţéļý ƒöļļöŵš.
  • SkeletonRef: ţĥé ƃļöçķ'š ţéẋţ îš ŕéñđéŕéđ. ΃ à ĥéļđ Original ḿàţçĥéš ţĥé ŕéñđéŕîñĝ, ţĥé öŕîĝîñàļ ƃýţéš àŕé ŵŕîţţéñ îñšţéàđ àñđ ţĥé éñçöđîñĝ þàšš îš šķîþþéđ; öţĥéŕŵîšé ţĥé ŕéñđéŕîñĝ îš ĤŢḾĻ-éñçöđéđ àñđ ŵŕîţţéñ. Àţţŕîƃüţé ŕ郚 šţîļļ šüƃšţîţüţé îñšîđé à ŕéþļàýéđ šþàñ.
  • SkeletonTrimmed: ŵŕîţţéñ öñļý ŵĥéñ ţĥé þŕéṽîöüš ŕéƒ ŕéñđéŕéđ àš ţĥé éñţŕý éẋþéçţš.
  • SkeletonLang: ŵĥéñ ŕéţàŕĝéţîñĝ àñđ ţĥé šţöŕéđ ṽàļüé îš ţĥé šàḿé ļàñĝüàĝé àš ţĥé šöüŕçé ļöçàļé, ţĥé ŵŕîţéŕ'š ţàŕĝéţ ļöçàļé îš éḿîţţéđ; öţĥéŕŵîšé ţĥé šţöŕéđ ṽàļüé ṽéŕƃàţîḿ.

Ŵŕîţéŕ ƒàļļƃàçķ çĥàîñ

Ţĥé ŵŕîţéŕ ţŕîéš ţĥŕéé ḿöđéš îñ öŕđéŕ:

  1. Šķéļéţöñ šţöŕé, ƃýţé-éẋàçţ: àṽàîļàƃļé ŵĥéñ SkeletonStoreConsumer.SetSkeletonStore() ŵàš çàļļéđ.
  2. Ŕé-þàŕšé öŕîĝîñàļ çöñţéñţ: ŕé-þàŕšéš ţĥé öŕîĝîñàļ ĤŢḾĻ ŵîţĥ à ĐÖḾ ŵàļķéŕ, þàţçĥéš ţŕàñšļàţîöñš îñţö ţĥé ţŕéé, àñđ ŕéñđéŕš ƃàçķ. Ŕéǫüîŕéš OriginalContentSetter.SetOriginalContent() öŕ SourcePathSetter.SetSourcePath().
  3. Ƃļöçķ-öñļý öüţþüţ: ŕéçöñšţŕüçţš à đöçüḿéñţ ƒŕöḿ ţĥé çöñţéñţ ḿöđéļ àñđ ţĥé šţŕüçţüŕàļ ļàýéŕ. Ţĥîš îš ţĥé çŕöšš-ƒöŕḿàţ þàţĥ (ĐöçĻàñĝ, Đöçļîñĝ öŕ ĐÖÇẊ çöñţéñţ ŕéñđéŕéđ àš çļéàñ ĤŢḾĻ), àñđ ţĥé ļàšţ ŕéšöŕţ ŵĥéñ ñö öŕîĝîñàļ çöñţéñţ îš àṽàîļàƃļé.

Ƒîļéš

ƑîļéŔöļé
core/format/skeleton.goŠķéļéţöñŠţöŕé ţýþé, éñţŕý ƒöŕḿàţ, îñţéŕƒàçéš, ţĥé ŵîŕîñĝ šéàḿ
core/format/skeleton_stream.goStreamSkeletonWrite, ţĥé šĥàŕéđ šţŕéàḿîñĝ ŵŕîţéŕ ĥéļþéŕ
core/format/extent.goLocateSkeleton, AlignSkeleton, Extent, Confined, LineRange: ŵĥéŕé éàçĥ ƃļöçķ šîţš îñ îţš šöüŕçé
core/diffscope/diffscope.goÜñîƒîéđ đ þàŕšîñĝ, àñđ ţĥé ƃļöçķš à đ'š ļîñéš ţöüçĥ
core/format/capturereader.goCaptureReader, ţĥé šļîđîñĝ ŵîñđöŵ ƒöŕ encoding/xml ŕéàđéŕš
core/formats/html/tokenreader.goŠîñĝļé-þàšš ţöķéñîžéŕ ŕéàđéŕ
core/formats/html/reader.goĐîšþàţçĥ: šķéļéţöñ šţöŕé → ţöķéñîžéŕ, éļšé → ĐÖḾ
core/formats/html/writer.goŠķéļéţöñ ḿöđé, ŕé-þàŕšé ƒàļļƃàçķ, ƃļöçķ-öñļý ƒàļļƃàçķ
core/formats/html/roundtrip_test.goƂýţé-éẋàçţ, ţŕàñšļàţîöñ, àñđ àţţŕîƃüţé ŕöüñđ-ţŕîþ ţéšţš
core/formats/json/streamscanner.go, tokenstream.goŢĥé šţŕéàḿîñĝ ĴŠÖÑ ţöķéñîžéŕ àñđ ţĥé šéàḿ ţĥé ŵàļķ ŕéàđš ţĥŕöüĝĥ
core/flow/filerunner.gostreamingFeed àñđ wireSkeleton: ţĥé þéŕ-ŕüñ šţŕéàḿîñĝ àñđ šķéļéţöñ đéçîšîöñ
host/toolrun.goNewWiredSkeleton öñ ţĥé ţööļ þàţĥ, ƒàîļîñĝ ţĥé ƒîļé öñ éŕŕöŕ