天天热议:【音频】syntax How to Write Custom Syntax
How to Write Custom Syntax
(资料图片仅供参考)
PostCSS can transform styles in any syntax, and is not limited to just CSS. By writing a custom syntax, you can transform styles in any desired format.
Writing a custom syntax is much harder than writing a PostCSS plugin, but it is an awesome adventure.
There are 3 types of PostCSS syntax packages:
Parserto parse input string to node’s tree.Stringifierto generate output string by node’s tree.Syntaxcontains both parser and stringifier.
Syntax
A good example of a custom syntax is SCSS. Some users may want to transform SCSS sources with PostCSS plugins, for example if they need to add vendor prefixes or change the property order. So this syntax should output SCSS from an SCSS input.
The syntax API is a very simple plain object, with parse& stringifyfunctions:
module.exports = { parse: require("./parse"), stringify: require("./stringify")}
Parser
A good example of a parser is Safe Parser, which parses malformed/broken CSS. Because there is no point to generate broken output, this package only provides a parser.
The parser API is a function which receives a string & returns a Rootnode. The second argument is a function which receives an object with PostCSS options.
const postcss = require("postcss")module.exports = function parse (css, opts) { const root = postcss.root() // Add other nodes to root return root}
Main Theory
There are many books about parsers; but do not worry because CSS syntax is very easy, and so the parser will be much simpler than a programming language parser.
The default PostCSS parser contains two steps:
Tokenizer which reads input string character by character and builds a tokens array. For example, it joins space symbols to a ["space", "\n "]token, and detects strings to a ["string", ""\"{""]token.Parser which reads the tokens array, creates node instances and builds a tree.
Performance
Parsing input is often the most time consuming task in CSS processors. So it is very important to have a fast parser.
The main rule of optimization is that there is no performance without a benchmark. You can look at PostCSS benchmarks to build your own.
Of parsing tasks, the tokenize step will often take the most time, so its performance should be prioritized. Unfortunately, classes, functions and high level structures can slow down your tokenizer. Be ready to write dirty code with repeated statements. This is why it is difficult to extend the default PostCSS tokenizer; copy & paste will be a necessary evil.
Second optimization is using character codes instead of strings.
// Slowstring[i] === "{"// Fastconst OPEN_CURLY = 123 // `{"string.charCodeAt(i) === OPEN_CURLY
Third optimization is “fast jumps”. If you find open quotes, you can find next closing quote much faster by indexOf:
// Simple jumpnext = string.indexOf(""", currentPosition + 1)// Jump by RegExpregexp.lastIndex = currentPosion + 1regexp.test(string)next = regexp.lastIndex
The parser can be a well written class. There is no need in copy-paste and hardcore optimization there. You can extend the default PostCSS parser.
Node Source
Every node should have sourceproperty to generate correct source map. This property contains startand endproperties with { line, column }, and inputproperty with an Inputinstance.
Your tokenizer should save the original position so that you can propagate the values to the parser, to ensure that the source map is correctly updated.
Raw Values
A good PostCSS parser should provide all information (including spaces symbols) to generate byte-to-byte equal output. It is not so difficult, but respectful for user input and allow integration smoke tests.
A parser should save all additional symbols to node.rawsobject. It is an open structure for you, you can add additional keys. For example, SCSS parser saves comment types (/* */or //) in node.raws.inline.
The default parser cleans CSS values from comments and spaces. It saves the original value with comments to node.raws.value.rawand uses it, if the node value was not changed.
Tests
Of course, all parsers in the PostCSS ecosystem must have tests.
If your parser just extends CSS syntax (like SCSS or Safe Parser), you can use the PostCSS Parser Tests. It contains unit & integration tests.
Stringifier
A style guide generator is a good example of a stringifier. It generates output HTML which contains CSS components. For this use case, a parser isn"t necessary, so the package should just contain a stringifier.
The Stringifier API is little bit more complicated, than the parser API. PostCSS generates a source map, so a stringifier can’t just return a string. It must link every substring with its source node.
A Stringifier is a function which receives Rootnode and builder callback. Then it calls builder with every node’s string and node instance.
module.exports = function stringify (root, builder) { // Some magic const string = decl.prop + ":" + decl.value + ";" builder(string, decl) // Some science};
Main Theory
PostCSS default stringifier is just a class with a method for each node type and many methods to detect raw properties.
In most cases it will be enough just to extend this class, like in SCSS stringifier.
Builder Function
A builder function will be passed to stringifyfunction as second argument. For example, the default PostCSS stringifier class saves it to this.builderproperty.
Builder receives output substring and source node to append this substring to the final output.
Some nodes contain other nodes in the middle. For example, a rule has a {at the beginning, many declarations inside and a closing }.
For these cases, you should pass a third argument to builder function: "start"or "end"string:
this.builder(rule.selector + "{", rule, "start")// Stringify declarations insidethis.builder("}", rule, "end")
Raw Values
A good PostCSS custom syntax saves all symbols and provide byte-to-byte equal output if there were no changes.
This is why every node has node.rawsobject to store space symbol, etc.
All data related to source code and not CSS structure, should be in Node#raws. For instance, postcss-scsskeep in Comment#raws.inlineboolean marker of inline comment (// commentinstead of /* comment */).
Be careful, because sometimes these raw properties will not be present; some nodes may be built manually, or may lose their indentation when they are moved to another parent node.
This is why the default stringifier has a raw()method to autodetect raw properties by other nodes. For example, it will look at other nodes to detect indent size and them multiply it with the current node depth.
Tests
A stringifier must have tests too.
You can use unit and integration test cases from PostCSS Parser Tests. Just compare input CSS with CSS after your parser and stringifier.
相关推荐:
精彩放送:
- []全球观点:瘦金体由谁所创?关于瘦金体由谁所创的介绍
- []全球信息:乘风破浪的姐姐四公淘汰了谁?乘风破浪的姐姐复活名单
- []环球报道:泰山门票多少钱一张2022 泰山门票价格
- []天天热讯:《爱的厘米》好看吗?佟丽娅佟大为撒狗粮 郭家铭与男主再续兄弟情
- []世界热议:林丹的个人资料曝光 林丹是谁?
- []视焦点讯!索爱手机w800c怎么样?索爱手机w800c综合评测与最新报价
- []环球热资讯!王力宏被娃哈哈解约后 看到他随身携带的水太佩服
- []环球实时:长丝巾有哪些系法?长丝巾的系法图解
- []世界通讯!捷安特770d怎么样?捷安特770d详细评测
- []硬盘s.m.a.r.t指标数据异常修复工具 硬盘的s m a r t指标数据异常怎么修复?
- []311是什么意思?关于311的详情介绍
- []世界简讯:HTC One X Recovery一键刷入步骤介绍 HTC One X Recovery一键刷入教程
- []当前快报:htc是什么牌子?htc手机的评测
- []环球热资讯!台式机硬盘报价如何?台式机硬盘尺寸
- []世界报道:羽毛球奥运冠军都有谁?国羽男子奥运冠军排名
- []全球球精选!诺亚舟np360学习机怎么样?诺亚舟np360性能介绍
- []定位赛10连胜什么段位?LOL S5定位赛胜率高为什么没有上段?
- []即时焦点:三星9050好不好?三星9050如何刷机?
- []世界时讯:纯甲类功放价格参考及其介绍 纯甲类功放的价格
- []世界快看点丨联想S890支持什么视频格式?联想S890支持RMVB播放吗?
- []操作系统有哪些类型?操作系统的特点是什么?
- []世界热文:手机钢化膜哪个品牌质量好?手机钢化膜的优缺点是什么?
- []死或生5最后一战怎么反击?死或生5最后一战反击技巧攻略
- []环球视点!谐波减速机优点是什么?齿轮式怎么滚动?
- []焦点快报!计算机主板结构你了解多少?计算机主板的分类
- []报道:计算机拨号连接无法建立连接怎么办?电信拨号上网连接不上的解决方法
- []怎么用电脑摄像头录像?电脑摄像头录像的使用方法
- []APP(ios、Android)实现充值的方案 ios中充值功能的2种方案
- []暴风影音如何倍速播放?暴风影音倍数播放的方法
- []Cubase延音踏板怎么设置?Cubase延音踏板设置延音效果
- []浏览器市场占有率排行表 2020年8月国内浏览器排行
- []【环球新要闻】人工智能算法是什么?简化图形文件
- []环球微动态丨光电耦合器是什么?光电耦合器工作原理详解
- []焦点简讯:百度云盒怎么预约购买?电视应用购买教程
- []全球微头条丨vice versa是什么意思?vice versa通常翻译
- []【环球报资讯】咸鱼Maya笔记 Maya界面是怎么组成的?
- []520还在画玫瑰?教你用MATLAB画个玫瑰花球
- []宾得镜头简介 镜头术语都有哪些?
- []世界热门:百度如何清除搜索框内的搜索历史记录?清除历史记录
- []小米与华为手机哪个好些?小米与华为手机详细评测
- []华为荣耀4C详细评测 再次刷新安卓手机性价比
- []世界新动态:人生中的第一个Java程序:HelloWorld
- []世界视点!arp防火墙哪个最好?风云arp防火墙的基本介绍
- []联想服务器linux系统raid驱动 IntelRAID 6.12版RAID卡驱动官方正式版下载
- []环球观速讯丨有哪些好看的电影推荐?吐血推荐250部必看电影
- []微动态丨我们为什么要上学?奥巴马开学演讲稿
- []环球热点!我的世界android制作教程 我的世界怎么去月球?
- []当前滚动:安卓怎么开启启动模式?Android四种启动模式
- []当前速读:南阳五中2021年高考成绩查询时间 南阳市五中举行2021年春期开学典礼
- []世界讯息:E. Border是什么?拓展欧几里得+mod分析
- []世界微资讯!电阻式触摸屏好用吗?电阻式触摸屏工作原理
- []实时:AssemblyInfo.cs文件的作用是什么?AssemblyInfo.cs文件详情
- []焦点热讯:小众国度酒店,如何异国生长?
- []世界时讯:中国铁建转让苏州京发地产30%股权 广州新铁鑫建接盘
- []今日播报!富临运业:截至2022年12月9日,公司股东人数为24,367人
- []华盛昌:公司正在积极推进呼吸机产品的国内医疗注册认证相关事宜
- []焦点播报:南雄长和物业拟转让南雄市壹城物业30%股权 底价30万元
- []全球信息:全国畜牧总站挂牌北京元立物业100%股权 转让底价为165万元
- []普利制药:当前公司生产及产能利用率情况正常,在建产能达到GMP标准的可使用状态后公司将进行商业化产投
- []每日快报!长株潭烟草物流园100%股权及2.32亿债权被挂牌 底价3.67亿
- []重点聚焦!上海茶叶进出口公司挂牌渠晨地产20%股权 底价1095万元
- []环球快播:三立期货12月19日早间内参——宏观
- []济南城建集团拟发7亿元公司债 利率询价区间为3%-4.8%
- []伟创电气:公司今年1-9月海外收入同比增长149.19%,后期数据敬请关注公司定期报告
- []最新快讯!华纺股份:公司严格遵照中国证监会、上海证券交易所对信息披露的要求披露公司相关信息,请,敬请谅解
- []天天看热讯:众泰要把车卖到中东!计划销售10000台,总价近7亿
- []世界最资讯丨衡水保衡房地产16.81亿摘得常山北明旗下原棉二分公司厂区用地
- []陈茂波:今年香港经济面对较大下行压力 估计收缩3.2%
- []热议:造富雪道 | “无人零售商” 友宝再闯港交所里的商业脉络
- []热文:区域新盘观察 | 半年去化仅15.5%!坐拥成都最大湿地公园的城投观澜东著怎么了?
- []世界快看点丨福建佳信置业摘福州永泰城峰镇50亩商服地 拟建四星级酒店
- []平安基金、华夏基金等成为西安高新区保障房公募REITs中标候选人
- []全球即时:新能源强配储能:山重水复仍“无路”
- []保险买了可以退吗
- []购房后怎么提取住房公积金 公积金在买房后如何提取
- []每日消息!小事记 | 荣万家收购物业公司 新加坡城市发展2.15亿英镑再收购学生公寓
- []三者险怎么网上买
- []天天动态:保险的作用和功能
- []世界观点:资本圈 | 华润置地35亿超短债完成注册 中海3年期公司债利率2.25%
- []住院互助金是什么意思 什么是住院互助金
- []【新要闻】荣万家拟以4535.3万收购盛行旅居生活服务 涉在管面积119万平
- []当前视点!合景泰富拟配售2.35亿股 筹资约4.67亿港元
- []国际航线回暖、航空需求恢复,五家上市航司提交11月运营成绩单
- []每日精选:福晟国际:清盘呈请聆讯押后至2023年4月14日
- []快看点丨西藏天路:拟以自有资金参与认购中国电建非公开发行股票
- []金花股份:西部投资3.4亿受让金花国际大酒店100%股权
- []【全球新要闻】福州长乐:按照人才层次提供购房补贴 符合条件最高补贴180万
- []每日焦点!特海国际通过港交所上市聆讯:翻台率下滑明显,张勇夫妇为实控人
- []泸州银行拟4.36亿元收购成都高新一物业 用作业务大楼
- []全球快资讯丨华南城拟50亿出售西安华南城69.35%股权予广东深基华园
- []热点评!透过携程财报看旅游业复苏;民航要多久才能迎来春天?| 一周速览
- []世界热点评!新加坡城市发展2.15亿英镑再收购英国伯明翰等地5个学生公寓
- []世界杯开赛两周 电视畅销榜前十海信占8个
- []华润置地35亿元超短期融资券完成注册 期限270天
- []每日讯息!招商蛇口再落地深圳光明区玉律东片区旧改 建面料逾80万平
- []世界杯观赛神器,Z世代消费者首选海信电视
- []中交地产10亿公司债利率确定为5.9% 此前询价区间4.5%-5.9%
- []每日时讯!中海企业30亿元公司债利率确定 3年期2.25%、5年期2.70%
- []每日热议!力合科创:公司严格遵守信息披露相关规定,有关信息请以公司指定信息披露媒体发布的公告为准
- []与法国决赛前日,阿根廷总统发文:不去卡塔尔,在家观看比赛
- 茉莉矿机新品X16重磅来袭,芯片性能较X4实现十倍提升
- 广州小伙夺冠粒上皇板栗炒制大赛,年炒板栗15吨练就美食秘笈
- 微动态丨今年A股IPO融资额同比增9% 超百家专精特新企业上市
- 全球消息!山西:创新发展光伏、风电、储能、氢能等新能源领域的数字技术应用
- 环球聚焦:商转公有什么利弊
- 三险是哪五种保险
- 当前快讯:华泰保险怎么退保
- 【全球聚看点】订单险退货免费吗
- 环球热讯:八闽保保险哪里买
- 世界杯观赛调研公布: Z世代消费者首选海信电视
- 今日报丨韩文秀:推动房地产业向新发展模式平稳过渡
- 利德曼:公司生产的生物化学原料主要应用于体外诊断产品等领域,目前不涉及新冠药物产品
- 防范化解重大风险 房地产与区域性、系统性风险成关键
- 天天关注:邮轮公司打造海上免税店;海航拟1元转让子公司股权 | 大公司简报
- 环球短讯!华东数控:公司主营业务为研发、生产和销售数控机床、普通机床及其关键功能部件,未研发钠离子电池生产设备
- 【热闻】科恒股份:公司与比亚迪多年来保持良好的合作关系,具体的业务金额未触及披露标准
- 快讯:新能源汽车“国补”年底终止,不是什么大问题
- 天天关注:腾讯又遭抛售!大股东套现3.18亿港元,减持VS回购,股价能否扛住?
- 全球观点:押注前海!招商蛇口拟并入南油集团24%股权等,19日起复牌
- 世界今日讯!单日票房时隔两月再破亿 影院行业复苏在望
- 最新资讯:重申房地产支柱地位!黎明来了,但23家房企已跌落千亿榜单
- 海尔旗下纳晖新能源与诸城市政府联合推进整村光伏开发 助力乡村振兴
- 每日热讯!交强险可以报几次
- 每日视点!德信服务附属为杭州瑞扬垫付本金额3.15亿元的贷款
- 天天快报!华安保险怎么退保
- 全球资讯:一次性趸缴是什么意思 什么是一次性趸缴
- 短期交强险怎么买
- 环球焦点!10天8板,半个月股价翻倍!布洛芬一粒难求?公司回应:行业无重大变化,正全力组织生产…
- 沪惠保在哪里投保
- 全球讯息:朗诗绿色生活收购北海朗润商业管理全部股权 总价2.02亿元
- “电池黑马”瑞浦兰钧增速惊人,动储双起飞
- 当前简讯:贝仕达克:12月15日公司高管李海俭减持公司股份合计3.84万股
- 当前快播:招商蛇口披露收购南油集团24%股权及招商前海实业2.89%股权方案
- 天天滚动:“云”上介绍特色文旅资源和精品旅游线路 向全国网友“种草”天津
- 博晖创新:公司目前没有静注COVID-19人免疫球蛋白产品和COVID-19恢复期血浆产品
- 动态焦点:英搏尔:12月15日公司高管李红雨减持公司股份合计5000股
- 【快播报】证监会新闻发言人就中美审计监管合作进展情况答记者问
- 快看点丨湖南发展计划转让旗下养老业务子公司82.5%股权
- 动态:深圳首个不限购“住宅”产品入市,剩44年产权
- 天天热点!九联科技股东减持820.1万股 套现7399.37万 2022年前三季度公司净利4725.24万
- 全球短讯!亚康股份:12月15日公司高管古桂林、王丰、曹伟减持公司股份合计14.91万股
- 招商积余调整组织架构 总部设立十个职能部门及两个业务部门
- 环球最资讯丨胜蓝股份:12月15日公司高管伍建华减持公司股份合计14万股
- 富力地产前11月总销售收入363.9亿元 单月销售11.7亿元
- 微资讯!如通股份:12月14日公司高管周晓峰减持公司股份合计10000股
- 全球焦点!特发服务投入1亿元进行现金管理 预计年化收益率1.50%-3.30%
- 鸿远电子:12月15日公司高管郑小丹减持公司股份合计8.28万股
- 储能电池技术方向:超300Ah叠片大容量电池,是未来主流方向
- 华润置地2021年第二期公司债将于12月20日付息 票面利率3.05%
- 世界观天下!佳电股份: 公司的轮毂电机主要为车用,且尚未形成量产
- 魅族有重磅的信息公布?不止有定档12月23日魅友大会......
- 中国中铁完成发行35亿元公司债 票面利率最高3.97%
- 天天微速讯:华发股份发行A股股票、收购铧金投资股权事宜获珠海国资委批复
- 世界短讯!中海2021年第五期公司债券将于12月20日付息
- 地缘政治风险阴魂不散 美国防务股选哪只
- 环球焦点!三友联众:公司连续八年入选中国电子元件百强企业,并在继电器领域的销售额连续八年排名第二
- 全球热议:上海电影补选杨莹为第四届董事会非独立董事候选人
- 沧州明珠:12月15日公司高管李繁联增持公司股份合计30万股
- 世界聚焦:详解酒店“采购到支付”全流程及自动化
- 天天热资讯!福建1-11月固定资产投资1.90万亿 房地产开发投资下降10.2%
- 泡泡玛特继续回购股份 斥资1037万港元回购55万股
- 天天观天下!凯撒文化:公司发展重心以IP游戏研发和运营为主,并未参与阿凡达发行及上映相关业务
- 水羊股份:御泥坊品牌在升级优化的过程中会根据市场反馈进行产品的迭代更新,产品迭代过程将有序推进
- 【环球新要闻】东阿阿胶:公司会通过定期报告对外披露前十大股东持股情况
- 热推荐:会德丰与九龙仓等共4家企业签订新物业服务协议
- 今日热门!中国航空运力回归,三大航再次跻身Top 20榜单
- 今日精选:武汉第五批供地第二场:3宗地收金20.37亿元
- 天天时讯:康华生物:股东减持是出于自身资金需求,与公司经营业绩无关
- 【快播报】回天新材:具体数据请查阅相关行业研究报告等
- 热议:财面儿丨远洋集团联合远洋服务拟向太古地产出售成都远洋太古里50%权益
- 【天天播资讯】麦格米特:公司经营一切正常,股价波动通常受多方面因素影响
- 家居丨创维集团行政总裁施驰兼任创维彩电总裁 原总裁李坚改任副总裁
- 用心交付 清远敏捷东城水岸喜迎业主归家
- 财面儿丨远洋集团ABS获通过 拟发行金额13.03亿元
- 70年不止音画探索,东芝电视全新100吋Z870系列沉浸式体验
- 世界热议:重磅!国家能源集团、华电开启储能容量租赁服务采购!
- 天天通讯!配储比例近40%!山东2022市场化并网风光项目公示
- 环球时讯:宿迁城建20亿元私募债状态更新为“已反馈”
- 环球速递!锦盛新材:公司相关数据未触及您描述的风险警示相关标准
- 环球看热讯:一个月港元拆息两连跌 报4.80577厘
- 中国电影:将建立更多合作 进一步拓展CINITY影厅覆盖率
- 时讯:中国电影:目前正在开发、创作中的项目有近60个
- 环球短讯!渤海轮渡:截至2022年11月10日,公司股东人数为30031户
- 每日播报!茂硕电源:截至2022年12月9日公司股东人数为30,404户
- 港会财局指港金融监管体系与国际接轨且稳健
- 英科医疗:在环境温度30°C±2°C的条件下,我们的产品检测报告显示可以持续数小时低于环境温度
- 头条:交易员正在抛售,但渣打称油价可能即将上涨!背后有何原因?
- 河南第二批独立储能示范项目遴选:不低于100MWh,优先采用全钒液流、钠离子、压缩空气储能技术
- 一张图:交易品种枢纽点+多空占比一览(2022/12/16周五)
- 前沿资讯!倒计时10天 | T宝带你看环球旅讯峰会精彩日程!
- 航空公司时隔三年重启招聘,民航人备战春运高峰
- 世界播报:投行称12月和明年1月初是黄金买点,明年Q4有望升至1890美元!
- 储能行业迎规模化扩充,电化学储能进入快速发展期(附主要技术路线分析图)
- 中信建投期货12月16日早间交易策略
- 美原油交易策略:油价受阻于21日均线,后市多头“凉”了?
- 环球快讯:越秀以底价8.19亿元竞得广州海珠区1宗地块
- 全球热推荐:新冠第一波感染高峰过后,春节期间的航班量会是多少?
- 当前快播:雅居乐集团:罗兵咸永道已辞任核数师
- 全球最资讯丨中交地产:拟发行10亿元公司债券
- 12月16日环球印务涨停分析:新冠疫苗,造纸,包装印刷概念热股